Commit f4bc3a0d authored by Zhangkai Wu's avatar Zhangkai Wu
Browse files

上传新文件

parent 93d206bf
Loading
Loading
Loading
Loading
+129 −0
Original line number Diff line number Diff line
%% Cell type:code id:93f440f5-34fe-4e60-b52f-e23bdb6a378a tags:

``` python
# NOTE:
# You may choose to use ChatGPT (or any AI-based tool) to assist with your assignment,
# but you must ensure that you fully understand the entire code.
# You are solely responsible for the work you submit.
# Please keep in mind: ChatGPT will not be available during the exam.
```

%% Cell type:code id:279418e8 tags:

``` python
import pandas
import pytorch_lightning as pl
import torch
import torch.nn as nn
from pytorch_lightning.callbacks import EarlyStopping
from sklearn.metrics import accuracy_score
from torch.utils.data import DataLoader, random_split, TensorDataset
```

%% Cell type:code id:b875409b tags:

``` python
class IrisClassification(pl.LightningModule):
    def __init__(self):
        super(IrisClassification, self).__init__()
        self.fc1 = nn.Sequential(
            nn.Linear(4, 10),
            nn.ReLU(inplace=True))
        self.fc2 = nn.Sequential(
            nn.Linear(10, 20),
            nn.ReLU(inplace=True))
        self.out = nn.Sequential(
            nn.Linear(20, 3))
            #nn.LogSoftmax()) # [Note] This line was incorrect in the hands-on video and has been commented out here.
        self.cross_entropy_loss = nn.CrossEntropyLoss()

    def forward(self, x):
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.out(x)
        return x

    def configure_optimizers(self):
        optimizer = torch.optim.Adam(self.parameters(), lr=0.01)
        return optimizer

    def training_step(self, batch, batch_idx):
        x, y = batch
        predictions = self.forward(x)
        loss = self.cross_entropy_loss(predictions, y)

        self.log("train_loss", loss)
        return loss

    def validation_step(self, batch, batch_idx):
        x, y = batch
        y_hat = self.forward(x)
        loss = self.cross_entropy_loss(y_hat, y)
        self.log("val_loss", loss)

    def test_step(self, batch, batch_idx):
        x, y = batch
        predictions = self.forward(x)
        loss = self.cross_entropy_loss(predictions, y)
        a, y_hat = torch.max(predictions, dim=1)
        test_acc = accuracy_score(y_hat, y)
        metrics = {"test_loss": loss, "test_acc": torch.tensor(test_acc)}
        self.log_dict(metrics)
        return metrics

    def test_epoch_end(self, outputs):
        avg_loss = torch.stack([x["test_loss"] for x in outputs]).mean()
        avg_test_acc = torch.stack([x["test_acc"] for x in outputs]).mean()
        logs = {"test_loss": avg_loss, "test_acc": avg_test_acc}
        results = {
            "avg_test_loss": avg_loss,
            "avg_test_acc": avg_test_acc,
            "log": logs,
            "progress_bar": logs,
        }
        self.log_dict(results)
        return results
```

%% Cell type:code id:0acdc2b3 tags:

``` python
if __name__ == "__main__":
    # Main function of script
    batch_size = 8

    dataset = pandas.read_csv("./iris.data.csv", header=None)
    # NOTE: Replace with the correct path to the iris.data.csv file on your system

    dataset.iloc[:, 4] = dataset.iloc[:, 4].astype('category')
    cat_columns = dataset.select_dtypes(['category']).columns
    dataset[cat_columns] = dataset[cat_columns].apply(lambda x: x.cat.codes)

    X = dataset.iloc[:, :4]
    y = dataset.iloc[:, 4]

    data = torch.Tensor(X.to_numpy()).float()
    labels = torch.Tensor(y.to_numpy()).long()

    data_set = TensorDataset(data, labels)
    train_set, test_set = random_split(data_set, [130, 20])

    train_set, val_set = random_split(train_set, [115, 15])

    train_loader = DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True, num_workers=8)
    val_loader = DataLoader(dataset=val_set, batch_size=batch_size, shuffle=False, num_workers=8)
    test_loader = DataLoader(dataset=test_set, batch_size=batch_size, shuffle=False, num_workers=8)

    model = IrisClassification()

    trainer = pl.Trainer(max_epochs=100, default_root_dir="./assignment",
                         callbacks=EarlyStopping(monitor="val_loss", min_delta=0.00, patience=5, verbose=True))

    trainer.fit(model, train_dataloader=train_loader, val_dataloaders=val_loader)
    trainer.test(model=model, test_dataloaders=test_loader)
```

%% Cell type:code id:6d28daae-5584-4d96-bddc-8ff9bfacb472 tags:

``` python
```