{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":5048,"databundleVersionId":868335,"sourceType":"competition"},{"sourceId":7468891,"sourceType":"datasetVersion","datasetId":4347722}],"dockerImageVersionId":30635,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"raw","source":"###### This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport torch, os, time, pickle\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torchvision import datasets, transforms, models\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.utils.data import random_split\nfrom datetime import datetime\n\n\nname = \"vgg16\"\nDATABASE = \"/kaggle/input/state-farm-distracted-driver-detection/imgs\"\nnum_epochs = 50\nBATCH_SIZE = 64","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_DIR = os.path.join(DATABASE, \"train\")\ntimestr = datetime.now().strftime(\"%m%d_%H%M%S\")\ndirctory = \"/kaggle/working/\"\n\ntransformations = transforms.Compose([\n    transforms.Resize((224, 224)),  # 将图像大小调整为224x224\n    transforms.ToTensor(),          # 将图像转换为Tensor\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 使用ImageNet的统计数据进行标准化\n])\n\n# 使用ImageFolder加载数据集\ndataset = datasets.ImageFolder(root=DATA_DIR, transform=transformations)\n\n\n# 假设 dataset 是您的完整数据集\n# total_size 是数据集的总大小\ntotal_size = len(dataset)\n\n# 计算测试集大小（20%）\ntest_size = int(total_size * 0.20)\n\n# 计算训练集大小\ntrain_size = total_size - test_size\n\n# 将数据集分为训练集和测试集\ntrain_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n\n\n# DataLoader\ntrain_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 初始化VGG16模型\nmodel = models.vgg16(pretrained=True)  # 加载预训练的VGG16模型\n\n# 修改分类器的最后一层，适应10个输出类\nnum_features = model.classifier[6].in_features\nmodel.classifier[6] = nn.Linear(num_features, 10)\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\n\n# 损失函数\ncriterion = nn.CrossEntropyLoss()\n\n# 优化器\noptimizer = optim.Adam(model.parameters(), lr=0.001)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(model, criterion, optimizer, num_epochs=10, save_interval = 25):\n    \n    train_losses = []\n    val_losses = []\n    train_accuracies = []\n    val_accuracies = []\n    best_acc = 0.0\n    \n    \n    since = time.time()\n    for epoch in range(num_epochs):\n        model.train()  # 设置模型为训练模式\n        train_loss = 0.0\n        train_corrects = 0\n        tdsz = 0\n        # 训练阶段\n        for inputs, labels in train_loader:\n            inputs, labels = inputs.to(device), labels.to(device)\n\n            optimizer.zero_grad()\n\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n            train_loss += loss.item()\n            _, preds = torch.max(outputs, 1)\n            train_corrects += torch.sum(preds == labels.data)\n            tdsz += inputs.size(0)\n\n        # 验证阶段\n        model.eval()  # 设置模型为评估模式\n        val_loss = 0.0\n        val_corrects = 0\n        vdsz = 0\n        with torch.no_grad():\n            for inputs, labels in test_loader:\n                inputs, labels = inputs.to(device), labels.to(device)\n\n                outputs = model(inputs)\n                loss = criterion(outputs, labels)\n\n                val_loss += loss.item()\n                _, preds = torch.max(outputs, 1)\n                val_corrects += torch.sum(preds == labels.data)\n                vdsz += inputs.size(0)\n\n        train_loss = train_loss / len(train_loader)\n        train_acc = train_corrects.double() / tdsz\n        val_loss = val_loss / len(test_loader)\n        val_acc = val_corrects.double() / vdsz\n\n        print(f\"Epoch {epoch}/{num_epochs - 1}\\t Train Loss: {train_loss:.4f} Acc: {train_acc:.4f}\\t Validation Loss: {val_loss:.4f} Acc: {val_acc:.4f}\\t\")\n\n        train_losses.append(train_loss)\n        val_losses.append(val_loss)\n        train_accuracies.append(train_acc)\n        val_accuracies.append(val_acc)\n        # 保存模型和数据\n        if (epoch + 1) % save_interval == 0 or epoch == num_epochs - 1:\n            results = {\n                'train_losses': train_losses,\n                'val_losses': val_losses,\n                'train_accuracies': train_accuracies,\n                'val_accuracies': val_accuracies\n            }\n            with open(dirctory + f'training_results_epoch_{epoch+1}.pkl', 'wb') as file:\n                pickle.dump(results, file)\n        # 保存最佳模型\n        if val_acc > best_acc:\n            best_acc = val_acc\n            torch.save(model.state_dict(), os.path.join(dirctory, name+timestr + 'best_model.pth'))\n\n\n    time_elapsed = time.time() - since\n    print('Training complete in {:.0f}m {:.0f}s'.format(\n        time_elapsed // 60, time_elapsed % 60))\n    return best_acc\n\nprint(\"begin...\")\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# acc = train_model(model, criterion, optimizer, num_epochs)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nsub = pd.read_csv(\"/kaggle/input/csvcsv/submission.csv\")\nsub.to_csv(\"submission.csv\", index = False)","metadata":{},"execution_count":null,"outputs":[]}]}