{"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"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# 导入包\nimport torch\nimport torch.nn as nn\nimport pandas as pd\nimport numpy as np\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom PIL import Image\nimport os\nimport matplotlib.pyplot as plt\nimport torchvision.models as models\nfrom tqdm import tqdm\nimport seaborn as sns\nimport cv2\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:23.817876Z","iopub.execute_input":"2022-12-22T06:50:23.818267Z","iopub.status.idle":"2022-12-22T06:50:26.129330Z","shell.execute_reply.started":"2022-12-22T06:50:23.818176Z","shell.execute_reply":"2022-12-22T06:50:26.128499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 看看label文件长啥样\nlabels_dataframe = pd.read_csv('/kaggle/input/solar-csv/train01.csv')\nlabels_dataframe.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.130766Z","iopub.execute_input":"2022-12-22T06:50:26.131119Z","iopub.status.idle":"2022-12-22T06:50:26.163346Z","shell.execute_reply.started":"2022-12-22T06:50:26.131080Z","shell.execute_reply":"2022-12-22T06:50:26.162590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_dataframe.describe()","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.165033Z","iopub.execute_input":"2022-12-22T06:50:26.165394Z","iopub.status.idle":"2022-12-22T06:50:26.192526Z","shell.execute_reply.started":"2022-12-22T06:50:26.165358Z","shell.execute_reply":"2022-12-22T06:50:26.191858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def barw(ax): \n    for p in ax.patches:\n        val = p.get_width()\n        x = p.get_x()+ p.get_width()\n        y = p.get_y() + p.get_height()/2\n        ax.annotate(round(val,2),(x,y))\n\nplt.figure(figsize = (10,4))\nax0 =sns.countplot(y=labels_dataframe['label'],order=labels_dataframe['label'].value_counts().index)\nbarw(ax0)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.193833Z","iopub.execute_input":"2022-12-22T06:50:26.194315Z","iopub.status.idle":"2022-12-22T06:50:26.324528Z","shell.execute_reply.started":"2022-12-22T06:50:26.194281Z","shell.execute_reply":"2022-12-22T06:50:26.323616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 把label文件排个序\nleaves_labels = sorted(list(set(labels_dataframe['label'])))\nn_classes = len(leaves_labels)\nprint(n_classes)\nleaves_labels[:10]","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.325878Z","iopub.execute_input":"2022-12-22T06:50:26.326224Z","iopub.status.idle":"2022-12-22T06:50:26.333204Z","shell.execute_reply.started":"2022-12-22T06:50:26.326189Z","shell.execute_reply":"2022-12-22T06:50:26.332212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 把label转成对应的数字\nclass_to_num = dict(zip(leaves_labels, range(n_classes)))\nclass_to_num","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.334488Z","iopub.execute_input":"2022-12-22T06:50:26.335216Z","iopub.status.idle":"2022-12-22T06:50:26.342836Z","shell.execute_reply.started":"2022-12-22T06:50:26.335182Z","shell.execute_reply":"2022-12-22T06:50:26.341937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 再转换回来，方便最后预测的时候使用\nnum_to_class = {v : k for k, v in class_to_num.items()}","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.344405Z","iopub.execute_input":"2022-12-22T06:50:26.344947Z","iopub.status.idle":"2022-12-22T06:50:26.350855Z","shell.execute_reply.started":"2022-12-22T06:50:26.344913Z","shell.execute_reply":"2022-12-22T06:50:26.350094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 继承pytorch的dataset，创建自己的\ndef f(x):\n#     print('shit',type(x))\n#     print('shit',x.shape)\n#     return x\n    \n    dim0, dim1 = x.shape\n    for i in range(dim0):\n#         print(i)\n#         print(len[[x[i]]])\n        for j in range(dim1):\n            if(x[i][j] > 60):\n                x[i][j] = min(255, x[i][j] + int(x[i][j] - 60) * 1.2)\n            else:\n                x[i][j] = max(0, x[i][j] - int(60 - x[i][j]) * 1.2)\n#     print(x.shape)\n#     print(type(x))\n    return x\n#     for i in range(0, 3):\n#         if(x[i] > 60):\n#             x[i] = min(255, x[i] + int(x[i] - 60) * 2)\n#         else:\n#             x[i] = max(0, x[i] - int(60 - x[i]) * 2)\n#         print('shit ',type(x))\n#     return x\n            \nclass LeavesData(Dataset):\n    def __init__(self, csv_path, file_path, mode='train', valid_ratio=0.2, resize_height=256, resize_width=256):\n        \"\"\"\n        Args:\n            csv_path (string): csv 文件路径\n            img_path (string): 图像文件所在路径\n            mode (string): 训练模式还是测试模式\n            valid_ratio (float): 验证集比例\n        \"\"\"\n        \n        # 需要调整后的照片尺寸，我这里每张图片的大小尺寸不一致#\n        self.resize_height = resize_height\n        self.resize_width = resize_width\n\n        self.file_path = file_path\n        self.mode = mode\n\n        # 读取 csv 文件\n        # 利用pandas读取csv文件\n        self.data_info = pd.read_csv(csv_path, header=None)  #header=None是去掉表头部分\n        # 计算 length\n        self.data_len = len(self.data_info.index) - 1\n        self.train_len = int(self.data_len * (1 - valid_ratio))\n        \n        if mode == 'train':\n            # 第一列包含图像文件的名称\n            self.train_image = np.asarray(self.data_info.iloc[1:self.train_len, 0])  #self.data_info.iloc[1:,0]表示读取第一列，从第二行开始到train_len\n            # 第二列是图像的 label\n            self.train_label = np.asarray(self.data_info.iloc[1:self.train_len, 1])\n            self.image_arr = self.train_image \n            self.label_arr = self.train_label\n        elif mode == 'valid':\n            self.valid_image = np.asarray(self.data_info.iloc[self.train_len:, 0])  \n            self.valid_label = np.asarray(self.data_info.iloc[self.train_len:, 1])\n            self.image_arr = self.valid_image\n            self.label_arr = self.valid_label\n        elif mode == 'test':\n            self.test_image = np.asarray(self.data_info.iloc[1:, 0])\n            self.image_arr = self.test_image\n            \n        self.real_len = len(self.image_arr)\n        \n        print('Finished reading the {} set of Leaves Dataset ({} samples found)'\n              .format(mode, self.real_len))\n\n    def __getitem__(self, index):\n        # 从 image_arr中得到索引对应的文件名\n        single_image_name = self.image_arr[index]\n\n        # 读取图像文件\n        img_as_img = Image.open(self.file_path + single_image_name)\n#         img_as_img=cv2.imread(self.file_path + single_image_name,cv2.IMREAD_COLOR)\n#         print(type(img_as_img))\n        # 如果需要将RGB三通道的图片转换成灰度图片可参考下面两行\n        if img_as_img.mode != 'L':\n            img_as_img = img_as_img.convert('L')\n\n        # 设置好需要转换的变量，还可以包括一系列的nomarlize等等操作\n        if self.mode == 'train':\n            transform = transforms.Compose([\n                transforms.Resize((224, 224)),\n                transforms.RandomHorizontalFlip(p=0.5),   #随机水平翻转 选择一个概率\n                transforms.ToTensor(),\n#                 transforms.Normalize()\n            ])\n        else:\n            # valid和test不做数据增强\n            transform = transforms.Compose([\n                transforms.Resize((224, 224)),\n                transforms.ToTensor(),\n#                 transforms.Normalize()\n            ])\n        \n        img_as_img = transform(img_as_img)\n\n        if(img_as_img.shape[0] == 1):\n            img_as_img = torch.stack((img_as_img[0], img_as_img[0], img_as_img[0]), 0)\n        if(img_as_img.shape[0] == 4):\n            img_as_img = torch.stack((img_as_img[0], img_as_img[1], img_as_img[2]), 0)\n\n#         if(img_as_img.shape[0] == 2):\n#             img_as_img = torch.stack((img_as_img[0], img_as_img[1], img_as_img[1]), 0)\n#         if(img_as_img.shape)\n#         if(img_as_img.shape[0]==4):\n#             print(type(Image.open(self.file_path + single_image_name)))\n#             print(img_as_img.shape)\n#         print(ty)\n#         print(self.image_arr[index])\n#         print('fuck ',img_as_img[0].shape)\n#         img_as_img = torch.stack((f(img_as_img[0]), f(img_as_img[1]), f(img_as_img[2])), 0)\n        if self.mode == 'test':\n            return img_as_img\n        else:\n            # 得到图像的 string label\n            label = self.label_arr[index]\n            \n            # 标签\n            number_label = class_to_num[label]\n            \n            # 返回每一个index对应的图片数据和对应的label\n            return img_as_img, number_label\n\n    def __len__(self):\n        return self.real_len\n","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.355153Z","iopub.execute_input":"2022-12-22T06:50:26.355719Z","iopub.status.idle":"2022-12-22T06:50:26.372028Z","shell.execute_reply.started":"2022-12-22T06:50:26.355684Z","shell.execute_reply":"2022-12-22T06:50:26.371194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = '/kaggle/input/solar-csv/train01.csv'\ntest_path = '/kaggle/input/solar-csv/test01.csv'\n# csv文件中已经images的路径了，因此这里只到上一级目录\nimg_path = '/kaggle/input/solar-panel-dust-detection/Detect_solar_dust/'\n\ntrain_dataset = LeavesData(train_path, img_path, mode='train')\nval_dataset = LeavesData(train_path, img_path, mode='valid')\ntest_dataset = LeavesData(test_path, img_path, mode='test')\nprint(train_dataset)\nprint(val_dataset)\nprint(test_dataset)","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.374728Z","iopub.execute_input":"2022-12-22T06:50:26.374969Z","iopub.status.idle":"2022-12-22T06:50:26.398089Z","shell.execute_reply.started":"2022-12-22T06:50:26.374945Z","shell.execute_reply":"2022-12-22T06:50:26.397146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 定义data loader\ntrain_loader = torch.utils.data.DataLoader(\n        dataset=train_dataset,\n        batch_size=8, \n        shuffle=False,\n        num_workers=5\n    )\n\nval_loader = torch.utils.data.DataLoader(\n        dataset=val_dataset,\n        batch_size=8, \n        shuffle=False,\n        num_workers=5\n    )\ntest_loader = torch.utils.data.DataLoader(\n        dataset=test_dataset,\n        batch_size=8, \n        shuffle=False,\n        num_workers=5\n    )","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.399373Z","iopub.execute_input":"2022-12-22T06:50:26.399700Z","iopub.status.idle":"2022-12-22T06:50:26.404790Z","shell.execute_reply.started":"2022-12-22T06:50:26.399667Z","shell.execute_reply":"2022-12-22T06:50:26.403924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 给大家展示一下数据长啥样\ndef im_convert(tensor):\n    image = tensor.to(\"cpu\").clone().detach()\n    image = image.numpy().squeeze()\n    image = image.transpose(1,2,0)\n    image = image.clip(0, 1)\n\n    return image\n\nfig=plt.figure(figsize=(20, 12))\ncolumns = 4\nrows = 2\n\ndataiter = iter(train_loader)\ninputs, classes = dataiter.next()\n\nfor idx in range (columns*rows):\n    ax = fig.add_subplot(rows, columns, idx+1, xticks=[], yticks=[])\n    ax.set_title(num_to_class[int(classes[idx])])\n    plt.imshow(im_convert(inputs[idx]))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:26.406151Z","iopub.execute_input":"2022-12-22T06:50:26.406752Z","iopub.status.idle":"2022-12-22T06:50:30.343462Z","shell.execute_reply.started":"2022-12-22T06:50:26.406718Z","shell.execute_reply":"2022-12-22T06:50:30.337191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 看一下是在cpu还是GPU上\ndef get_device():\n    return 'cuda' if torch.cuda.is_available() else 'cpu'\n\ndevice = get_device()\nprint(device)","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:30.345828Z","iopub.execute_input":"2022-12-22T06:50:30.346182Z","iopub.status.idle":"2022-12-22T06:50:30.437905Z","shell.execute_reply.started":"2022-12-22T06:50:30.346138Z","shell.execute_reply":"2022-12-22T06:50:30.436173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 是否要冻住模型的前面一些层\ndef set_parameter_requires_grad(model, feature_extracting):\n    if feature_extracting:\n        model = model\n        for param in model.parameters():\n            param.requires_grad = False\n\n# alexnet模型\ndef alexnet_model(num_classes, feature_extract = False, use_pretrained = True):\n    model_ft = models.alexnet(pretrained = use_pretrained)\n    set_parameter_requires_grad(model_ft, feature_extract)\n    num_ftrs = model_ft.classifier[6].in_features\n    model_ft.classifier[6] = nn.Sequential(nn.Linear(num_ftrs, num_classes))\n    return model_ft\n\n# vgg模型\ndef vgg_model(num_classes, feature_extract = False, use_pretrained = True):\n    model_ft = models.vgg19(pretrained = use_pretrained)\n    set_parameter_requires_grad(model_ft, feature_extract)\n    num_ftrs = model_ft.classifier[6].in_features\n    model_ft.classifier[6] = nn.Sequential(nn.Linear(num_ftrs, num_classes))\n    return model_ft\n\n# inception_v3模型\ndef googlenet_model(num_classes, feature_extract = False, use_pretrained = True):\n    model_ft = models.inception_v3(aux_logits=False, pretrained = use_pretrained)\n    set_parameter_requires_grad(model_ft, feature_extract)\n    num_ftrs = model_ft.fc.in_features\n    model_ft.fc = nn.Sequential(nn.Linear(num_ftrs, num_classes))\n    return model_ft\n\n# resnet101模型\ndef res_model(num_classes, feature_extract = False, use_pretrained = True):\n    model_ft = models.resnet101(pretrained = use_pretrained)\n    set_parameter_requires_grad(model_ft, feature_extract)\n    num_ftrs = model_ft.fc.in_features\n    model_ft.fc = nn.Sequential(nn.Linear(num_ftrs, num_classes))\n    return model_ft\n\n# densenet161模型\ndef dense_model(num_classes, feature_extract = False, use_pretrained = True):\n    model_ft = models.densenet161(pretrained = use_pretrained)\n    set_parameter_requires_grad(model_ft, feature_extract)\n    num_ftrs = model_ft.classifier.in_features\n    model_ft.classifier = nn.Sequential(nn.Linear(num_ftrs, num_classes))\n    return model_ft","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:30.439280Z","iopub.execute_input":"2022-12-22T06:50:30.439756Z","iopub.status.idle":"2022-12-22T06:50:30.464767Z","shell.execute_reply.started":"2022-12-22T06:50:30.439719Z","shell.execute_reply":"2022-12-22T06:50:30.463604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 超参数\nlearning_rate = 2e-7\nweight_decay = 5e-7\nnum_epoch = 50\nmodel_path = './pre_dense_model.ckpt'","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:30.466194Z","iopub.execute_input":"2022-12-22T06:50:30.466705Z","iopub.status.idle":"2022-12-22T06:50:30.478266Z","shell.execute_reply.started":"2022-12-22T06:50:30.466667Z","shell.execute_reply":"2022-12-22T06:50:30.477220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# 初始化一个模型，并将其放在指定的设备上\nmodel = dense_model(2)\nmodel = model.to(device)\nmodel.device = device\n# 对于分类任务，使用交叉熵作为性能的度量\ncriterion = nn.CrossEntropyLoss()\n\noptimizer = torch.optim.Adam(model.parameters(), lr = learning_rate, weight_decay=weight_decay)\n\n# 训练周期数\nn_epochs = num_epoch\n\nbest_acc = 0.0\nv_los = []\nv_acc = []\nt_los = []\nt_acc = []\nfor epoch in range(n_epochs):\n    # 训练前确保模型处于训练模式\n    model.train() \n    # 用来记录训练信息\n    train_loss = []\n    train_accs = []\n    # 分批迭代训练集\n    for batch in tqdm(train_loader):\n        # 批处理由图像数据和相应的标签组成\n        imgs, labels = batch\n        imgs = imgs.to(device)\n        labels = labels.to(device)\n        logits = model(imgs)\n        # 计算交叉熵损失\n        # 不需要在计算交叉熵之前应用softmax，因为它是自动完成的\n        loss = criterion(logits, labels)\n        \n        # 在前一步中存储在参数中的梯度应该首先清除。\n        optimizer.zero_grad()\n        # 计算参数的梯度\n        loss.backward()\n        # 用计算的梯度更新参数\n        optimizer.step()\n        \n        # 计算当前批处理的精度\n        acc = (logits.argmax(dim=-1) == labels).float().mean()\n\n        # 记录损失值和准确性\n        train_loss.append(loss.item())\n        train_accs.append(acc)\n        \n    # 训练集的平均损失值和准确度是记录值的平均值\n    train_loss = sum(train_loss) / len(train_loss)\n    train_acc = sum(train_accs) / len(train_accs)\n    t_los.append(train_loss)\n    t_acc.append(train_acc)\n    # 打印信息\n    print(f\"[ Train | {epoch + 1:03d}/{n_epochs:03d} ] loss = {train_loss:.5f}, acc = {train_acc:.5f}\")\n    \n    \n    # 确保模型处于eval模式\n    model.eval()\n    # 它们用于记录验证集的信息。\n    valid_loss = []\n    valid_accs = []\n    \n    # 分批迭代验证集\n    for batch in tqdm(val_loader):\n        imgs, labels = batch\n        # 使用torch.no_grad()加速前进进程\n        with torch.no_grad():\n            logits = model(imgs.to(device))\n            \n        # 计算损失\n        loss = criterion(logits, labels.to(device))\n\n        # 计算当前批处理的精度\n        acc = (logits.argmax(dim=-1) == labels.to(device)).float().mean()\n\n        # 记录损失值和准确性\n        valid_loss.append(loss.item())\n        valid_accs.append(acc)\n        \n    # 整个验证集的平均损失和准确度是记录值的平均值\n    valid_loss = sum(valid_loss) / len(valid_loss)\n    valid_acc = sum(valid_accs) / len(valid_accs)\n    \n    v_los.append(valid_loss)\n    v_acc.append(valid_acc)\n    \n    # 打印信息\n    print(f\"[ Valid | {epoch + 1:03d}/{n_epochs:03d} ] loss = {valid_loss:.5f}, acc = {valid_acc:.5f}\")\n    \n    # 如果模型改进了，那么在这个位置保存一个检查点\n    if valid_acc > best_acc:\n        best_acc = valid_acc\n        torch.save(model.state_dict(), model_path)\n        print('saving model with acc {:.3f}'.format(best_acc))","metadata":{"execution":{"iopub.status.busy":"2022-12-22T06:50:30.479844Z","iopub.execute_input":"2022-12-22T06:50:30.480217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"saveFileName = './submission.csv'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## 预测\nmodel = dense_model(2)\n\n# 从检查点创建模型和负载权重\nmodel = model.to(device)\nmodel.load_state_dict(torch.load(model_path))\n\n# 确保模型处于eval模式\nmodel.eval()\n\n# 初始化一个列表来存储预测。\npredictions = []\n# 分批迭代测试集。\nfor batch in tqdm(test_loader):\n    \n    imgs = batch\n    with torch.no_grad():\n        logits = model(imgs.to(device))\n    \n    # 将logit最大的班级作为预测并记录。\n    predictions.extend(logits.argmax(dim=-1).cpu().numpy().tolist())\n\npreds = []\nfor i in predictions:\n    preds.append(num_to_class[i])\n\ntest_data = pd.read_csv(test_path)\ntest_data['label'] = pd.Series(preds)\nsubmission = pd.concat([test_data['image'], test_data['label']], axis=1)\nsubmission.to_csv(saveFileName, index=False)\nprint(\"Done!!!!!!!!!!!!!!!!!!!!!!!!!!!\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport random\n\nprint(type(v_acc))\nprint(len(v_acc))\nprint(type(t_acc))\nprint(len(t_acc))\nprint(type(v_los))\nprint(len(v_los))\nprint(type(t_los))\nprint(len(t_los))\n\nx = [i for i in range(1, 51)]\n\nfig, axes = plt.subplots(2, 1, figsize = (8, 12))\n\n# plot\nax1 = plt.subplot(211)\nax1.plot(x, v_los, label = \"Validation loss\")\nloss_mx = min(v_los)\nloss_pos = v_los.index(loss_mx) + 1\nax1.scatter(loss_pos, loss_mx, color = 'r', label = 'best epoch')\nax1.plot(x, t_los, label = \"Training loss\")\nax1.set_title(\"Training and Validation Loss\")\nax1.set_ylabel('Loss')\nax1.set_xlabel('Epochs')\nplt.grid()\nplt.legend()\n\nax2 = plt.subplot(212)\nax2.plot(x, v_acc, label = \"Validation Accuracy\")\nacc_mx = max(v_acc)\n# print(type(acc_mx))\nacc_pos = v_acc.index(acc_mx) + 1\nax2.scatter(acc_pos, float(acc_mx), color = 'r', label = 'best epoch')\nax2.plot(x, t_acc, label = \"Training Accuracy\")\nax2.set_title(\"Training and Validation Accuracy\")\nax2.set_ylabel('Accuracy')\nax2.set_xlabel('Epochs')\n\n# data.plot.bar(ax=axes[0], color='b', alpha = 0.5)\n# data.plot.barh(ax=axes[1], color='k', alpha = 0.5)\nplt.legend()\nplt.grid()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import seaborn as sns\nfrom sklearn.metrics import confusion_matrix\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import classification_report\nfrom sklearn.metrics import confusion_matrix\nimport pandas as pd\nimport sklearn.metrics as sm\n\ntest_dataframe = pd.read_csv('/kaggle/input/solar-csv/test01.csv')\ny_test = test_dataframe['label']\npred_dataframe = pd.read_csv('/kaggle/working/submission.csv')\ny_pre = pred_dataframe['label']\n# print(y_pre)\nT = 0\nfor i in range(0, len(y_test)):\n    # print()\n    if y_pre[i] == y_test[i]:\n        T += 1\n\nprint('Accuracy:',T/len(y_pre)) #输出模型准确度\nprint(classification_report(y_test,y_pre)) #预测报告\nprint(confusion_matrix(y_test,y_pre)) #输出混淆矩阵\nm = sm.confusion_matrix(y_test, y_pre)\n\ntn, fp, fn, tp = confusion_matrix(y_test, y_pre).ravel()\nplt.imshow(m, cmap=plt.cm.Blues)\nplt.xticks([0,1])\nplt.yticks([0,1])\nplt.xlabel(\"Predict\")\nplt.ylabel(\"True\")\n\nplt.text(x=0-0.1, y=0, s=\"TP:\"+str(tp), color='black')\nplt.text(x=1-0.1, y=0, s=\"FN:\"+str(fn), color='black')\nplt.text(x=0-0.1, y=1, s=\"FP:\"+str(fp), color='black')\nplt.text(x=1-0.1, y=1, s=\"TN:\"+str(tn), color='black')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nos.chdir('/kaggle/working')\nprint(os.getcwd())\nprint(os.listdir(\"/kaggle/working\"))\nfrom IPython.display import FileLink\nFileLink('pre_dense_model.ckpt')","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}