【3DCNN示例】

import h5py
"""读取数据"""
path_dir="./archive/"
with h5py.File(path_dir+"full_dataset_vectors.h5", "r") as data:
    X_train = data["X_train"][:]
    y_train = data["y_train"][:]
    X_test = data["X_test"][:]
    y_test = data["y_test"][:]

# print('X_train   :   Shape:', X_train.shape, '         Type:', type(X_train))
# print('Y_train   :   Shape:',y_train.shape, '              Type:', type(y_train))
# print('X_test    :   Shape:', X_test.shape, '          Type:', type(X_test))
# print('Y_test    :   Shape:', y_test.shape, '               Type:', type(y_test))

"""重塑数据——3D空间中的MNIST 图像大小为 16x16x16"""
import numpy as np
import torch
def Transform_images_dataset (Data):
    #Binarize_images_dataset
    Th=0.2
    Upper=1
    Lower=0
    Data = np.where(Data>Th, Upper, Lower)
    #Data_transform_channels
    Data = Data.reshape(Data.shape[0], 1, 16,16,16)
    """使用NumPy库中的stack()函数将数组Data沿着最后一个维度复制3次,
       并将它们沿着新的最后一个维度堆叠在一起,以创建一个新的3维数组"""
    Data = np.stack((Data,) * 3, axis=-1)
    return(torch.as_tensor(Data))

# 初始shape为(10000, 4096),转换之后变成torch.Size([10000, 1, 16, 16, 16, 3])
X_train = Transform_images_dataset(X_train)
# 初始shape为(2000, 4096),转换之后变成torch.Size([2000, 1, 16, 16, 16, 3])
X_test = Transform_images_dataset(X_test)

def One_hit_data (target):
    # Convert To Torch Tensor
    Target_tensor = torch.as_tensor(target)
    # Create One-Hot Encodings Of Labels
    """使用PyTorch中的函数torch.nn.functional.one_hot()
    将Target_tensor转换为one-hot编码形式。其中,num_classes=10
    表示生成的one-hot向量维度为10,即Target_tensor中包含的类别数量为10"""
    One_hot = torch.nn.functional.one_hot(Target_tensor, num_classes=10)
    return(One_hot)
# y_train.shape——>torch.Size([10000, 10])
y_train= One_hit_data (y_train)
# y_test.shape——>torch.Size([2000, 10])
y_test= One_hit_data (y_test)
# print('X_train   :   Shape:', X_train.shape, '          Type:', type(X_train))
# print('Y_train   :   Shape:', Y_train.shape, '                     Type:', type(Y_train))
# print('X_test    :   Shape:', X_test.shape, '           Type:', type(X_test))
# print('Y_test    :   Shape:', Y_test.shape, '                      Type:', type(Y_test))

import pandas as pd
import numpy as np
from tqdm.auto import tqdm
import os
import matplotlib.pyplot as plt
import torch
from torch.autograd import variable
import  torch.nn as nn
import torch.nn.functional as F
from torch.optim import *
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
from sklearn.metrics import confusion_matrix
import seaborn as sns

"""创建用于图像分类的三维卷积神经网络模型"""
class CNN_classification_model(nn.Module):
    # 使用的是mnist数据集
    def __init__(self,num_classes=10):
        super(CNN_classification_model, self).__init__()
        self.Model = nn.Sequential(
            # Conv Layer 1
            nn.Conv3d(3, 32, kernel_size=(3, 3, 3), padding=0),
            nn.ReLU(),
            nn.MaxPool3d((2, 2, 2)),

            # Conv Layer 2
            nn.Conv3d(32, 64, kernel_size=(3, 3, 3), padding=0),
            nn.ReLU(),
            nn.MaxPool3d((2, 2, 2)),

            # Flatten
            nn.Flatten(),
            # Linear 1
            nn.Linear(2 ** 3 * 64, 128),
            # Relu
            nn.ReLU(),
            # BatchNorm1d
            nn.BatchNorm1d(128),
            # Dropout
            nn.Dropout(p=0.15),
            # Linear 2
            nn.Linear(128, num_classes)
        )

    def forward(Self, X):
        # Set 1
        Out = Self.Model(X)
        return Out

"""定义准确率函数,用于求准确率"""
def AccuracyFUNCTION (Predicted, Targets):
    C=0
    for i in range(len(Targets)):
        if (Predicted[i] == Targets[i]):
            C+=1
    Accuracy =  C / float(len(Targets))
    return(Accuracy)

"""训练模型"""
batch_size = 100
# Pytorch train and test sets
train = torch.utils.data.TensorDataset(X_train.float(),y_train.long())
test = torch.utils.data.TensorDataset(X_test.float(),y_test.long())
# data loader with pytorch
train_loader = torch.utils.data.DataLoader(train, batch_size = batch_size, shuffle = False)
test_loader = torch.utils.data.DataLoader(test, batch_size = batch_size, shuffle = False)
# we have 10 classes
num_classes = 10
# The number of epochs (here the number of iterations is = 5000 / we have 50 epochs a batch size is 100 / 50*100=5000)
num_epochs = 5
# 3D model
model = CNN_classification_model()
#You can use the GPU by typing: model.cuda()
# print(model)
# Loss function : Cross Entropy
error = nn.CrossEntropyLoss()
# Learning rate : learning_r = 0.01
learning_r = 0.01
# SGD optimizer
optimizer = torch.optim.SGD(model.parameters(), lr=learning_r)

# ***********************************************************************training***********************************
itr = 0
loss_list = []
accuracy_list = []
for epoch in range(num_epochs):
    # tqdm则是一个Python的进度条库,用于显示循环迭代的进度。
    for i, (images, labels) in tqdm(enumerate(train_loader)):
        # 将images(100, 1, 16, 16, 16, 3)重塑为(100, 3, 16, 16, 16)
        train = torch.tensor(images.view(100, 3, 16, 16, 16))
        labels = torch.tensor(labels)
        # zero_grad : Clear gradients
        optimizer.zero_grad()
        # Forward propagation / CNN_classification_model
        outputs = model(train)
        # Calculate loss value / using cross entropy function
        """将一个多类别的标签张量(tensor)转换为只有一个标签的张量,沿着最后
        一个维度找到每个样本中具有最高值的索引,并将其作为该样本的标签."""
        labels = labels.argmax(-1)
        loss = error(outputs, labels)
        loss.backward()
        # Update parameters using SGD optimizer
        optimizer.step()

        # calculate the accuracy using test data
        itr += 1
        if itr % 100 == 0:
            # Prepare a list of correct results and a list of anticipated results.
            listLabels = []
            listpredicted = []
            # test_loader
            for images, labels in test_loader:

                test = torch.tensor(images.view(100, 3, 16, 16, 16))
                # Forward propagation
                outputs = model(test)
                # print(dir(outputs))
                # Get predictions from the maximum value
                # torch.max(outputs.data, 1)返回每行输出中最大的元素值和每行最大元素所在的列索引
                # 列索引作为最终的预测结果 predicted
                predicted = torch.max(outputs.data, 1)[1]

                # used to convert the output to binary variables
                predicted = One_hit_data(predicted)
                # Create a list of predicted data
                predlist = []
                for i in range(len(predicted)):
                    # print(predicted[i])
                    # 用于找到张量 predicted[i] 中最大值所在的索引位置,并返回该索引
                    p = int(torch.argmax(predicted[i]))
                    # print(p)
                    predlist.append(p)

                listLabels += (labels.argmax(-1).tolist())
                listpredicted += (predlist)

            # calculate Accuracy
            accuracy = AccuracyFUNCTION(listpredicted, listLabels)
            # 打印这一次迭代的loss
            print('Iteration: {}  Loss: {}  Accuracy: {}'.format(itr, loss.data, accuracy))

            # store loss and accuracy. They'll be required to print the curve.
            #每当迭代符合itr % 100 == 0这个条件,就把这一次的loss和accuracy存入各自的list
            loss_list.append(loss.data)
            accuracy_list.append(accuracy)

"""Display The Accuracy Curve"""
sns.set()
sns.set(rc={'figure.figsize': (12, 7)}, font_scale=1)
plt.plot(accuracy_list, 'b')
plt.plot(loss_list, 'r')

plt.rcParams['figure.figsize'] = (7, 4)
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.title("Training Step:  Accuracy Vs Loss ")
plt.legend(['Accuracy', 'Loss'])
plt.show()

"""Display The Confusion Matrix """
predictionlist=[]
for i,(images, labels) in tqdm(enumerate(train_loader)):
    # 将images(100, 1, 16, 16, 16, 3)重塑为(100, 3, 16, 16, 16)
    train = torch.tensor(images.view(100, 3, 16, 16, 16))
    labels = torch.tensor(labels)
    outputs = model(train)

    #这里是因为报错Labels1和Predictionlist的长度不一致,
    #暂时没别的办法,只能先这样控制一下
    if len(predictionlist)<100:
        for i in range(len(outputs)):
            p = int(torch.argmax(outputs[i]))
            predictionlist.append(p)

        Labels1=labels.argmax(-1).tolist()
        Labels1= [str(X) for X in Labels1]
        # print(len(Labels1))
        Predictionlist= [str(X) for X in predictionlist]
        # print(len(Predictionlist))
        LabelsLIST = ['0','1', '2','3', '4','5', '6','7', '8','9']
        Cm = confusion_matrix(Labels1, Predictionlist, labels=LabelsLIST)
        ConfusionMatrixDisplay(Cm).plot()
        #******************** Color Of Confusion Matrix

        ax= plt.subplot()
        sns.heatmap(Cm, annot=True, ax = ax, cmap=plt.cm.Blues)

        #Annot=True To Annotate Cells
        # Labels, Title And Ticks
        ax.set_xlabel('Predicted Labels')
        ax.set_ylabel('True Labels')
        ax.set_title('Confusion Matrix')
        ax.xaxis.set_ticklabels( ['0','1', '2','3', '4','5', '6','7', '8','9'])
        ax.yaxis.set_ticklabels(['0','1', '2','3', '4','5', '6','7', '8','9'])
        plt.rcParams['figure.figsize'] = (8, 7)
        plt.show()

 

 原文链接:ReachIt (reachiteasily.com)icon-default.png?t=N2N8https://www.reachiteasily.com/2021/06/3d-convolutional-neural-network-pytorch.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值