刘二大人的Pytorch笔记

1.前言

2.线性回归

2.1用numpy模拟计算predict和计算loss的过程

import numpy as np
import matplotlib.pyplot as plt
import sys
#大致模型为y=x*w
x_data=[1.0,2.0,3.0]
y_data=[2.0,4.0,6.0]

def forward(x):
    return x*w

def loss(y_pred,y):
    return np.power(y_pred-y,2)

w_list=[]
mse_list=[]

length=len(x_data)
for w in np.arange(0.0,4.1,0.1):
    print(f"-----------w={w}-------------------------")
    loss_sum=0
    for x_val,y_val in zip(x_data,y_data):
        y_pred=forward(x_val)
        loss_val=loss(y_pred,y_val)
        loss_sum+=loss_val
        print(f'x_val={x_val},y_val={y_val},y_pred={y_pred},loss_val={loss_val}')
    print(f"-----------MSE={loss_sum/length}----------")
    w_list.append(w)
    mse_list.append(loss_sum/length)

plt.plot(w_list,mse_list)
plt.ylabel("Loss")
plt.xlabel('w')
plt.show()

 

 3.梯度下降

3.1numpy模拟梯度下降,用y=x*w的模型

import numpy as np
import matplotlib.pyplot as plt

x_data=[1.0,2.0,3.0,4.0,5.0]
y_data=[2.0,4.0,6.0,8.0,10.0]

# 权重初始化为1
w=1.0

def forward(x):
    return x*w

#mean square error
# 批量数据的损失的平均值
def loss(x_data,y_data):
    loss_sum=0
    for x,y in zip(x_data,y_data):
        y_pred=forward(x)
        loss_sum+=(y_pred-y)**2
    return loss_sum/len(x_data)

#计算w的梯度,就是代价函数对w求导,这里的w只有一个,因为x只有一个列,x只有一个特征
# 批量数据的导数的平均值
# d(x*w-y)**2 / dw = 2*w*(x*w-y)
def gradient(x_data,y_data):
    gradient=0
    for x,y in zip(x_data,y_data):
        gradient+=(x*w-y)*x*2
    return gradient/len(x_data)


mse_list=[]
w_list=[]
print("before training:",6,forward(6))
for epoch in range(100):
    loss_val=loss(x_data,y_data)
    mse_list.append(loss_val)
    grad_val=gradient(x_data,y_data)
    #梯度更新
    w-=0.01*grad_val
    w_list.append(w)
    print(f"Epoch={epoch}, w={w},loss={loss_val}")
print("Predict(after training)",6,forward(6))


print(len(x_data))
print(len(y_data))


# ---------------画个图----------------
import matplotlib.pyplot as plt
import sys

# 因为forward函数中的x*w是单个数之间相乘
def forward2(x):
    result=[xi * w for xi in x]
    return result

fig, axes = plt.subplots(nrows=1, ncols=2)

axes[0].plot(w_list,mse_list)
axes[0].set_xlabel("Loss")
axes[0].set_ylabel("w")
axes[0].legend()

axes[1].scatter(x_data,y_data,color="blue",s=100,label="real data")
axes[1].plot(x_data,forward2(x_data),color="orange",label="linear model")
axes[1].set_xlabel("x_data")
axes[1].set_ylabel("y_data")
axes[1].legend()

plt.show()

4.反向传播

4.1pytorch模拟梯度下降,用y=x*w的模型,loss.backword()自动求梯度,w开启存梯度的空间

import torch
import numpy as np

x_data=[1.0,2.0,3.0]
y_data=[2.0,4.0,6.0]

w=torch.Tensor([1.0])
w.requires_grad=True

#因为w是tensor,torch把运算结果自动转为tensor
def forward(x):
    return x*w
#这个方法返回的也是tensor
def loss(x,y):
    y_pred=forward(x)
    return (y_pred-y)**2

print("predict(before training),",4,forward(4).item())

epoches=100
loss_list=[]
for epoch in range(epoches+1):
    # 保存一个轮次所有样本的损失
    loss_sum=0
    for x,y in zip(x_data,y_data):
        #loss_val返回的是tensor,具有计算图功能,能进行反向传播,
        # 本例中,loss_val是一个数
        loss_val=loss(x,y)

        loss_sum+=loss_val.item()

        loss_val.backward()
        print("\tgrad:",x,y,w.grad.item())
        #w.data不需要构建计算图,不需要w.backward(),为了节省空间不用tensor类型
        # 梯度下降,后续可用optimizer.step()来处理
        w.data=w.data-0.01*w.grad.data
        w.grad.data.zero_()
    # print("progress:",epoch,loss_val.item())
    # 保存一个轮次的所有样本的平均损失
    loss_list.append(loss_sum/len(x_data))
print("predict(after training)",4,forward(4).item())



import matplotlib.pyplot as plt
import sys
fig, axes = plt.subplots(nrows=1, ncols=2)

# x_data-->tensor(list)-->
# x_data和forward(x_data)不是单个数不能用item(),detach().numpy()来转换
y_pred=forward(torch.tensor(x_data)).tolist()
print(y_pred)

axes[0].scatter(x_data,y_data,color="blue",s=100,label="real data")
axes[0].plot(x_data,y_pred,color="orange",label="linear model")
axes[0].set_xlabel("x_data")
axes[0].set_ylabel("y_data")
axes[0].legend()

axes[1].plot(np.arange(0,epoches+1,1),loss_list)
axes[1].set_xlabel("epoches")
axes[1].set_ylabel("loss")
axes[1].legend()

plt.show()

5.Pytorch实现线性回归

5.1 pytorch模拟y=x*w的线性模型,构建一个1x1的全连接层,使用optimizer.step()来梯度下降

import torch
import sys
import numpy as np
#3行1列的二位tensor
x_data=torch.Tensor([[1.0],
                     [2.0],
                     [3.0]])
y_data=torch.Tensor([[2.0],
                     [4.0],
                     [6.0]])

class LinearModel(torch.nn.Module):
    def __init__(self) :
        super(LinearModel,self).__init__()
        self.linear=torch.nn.Linear(1,1)
    def forward(self,x):
        y_pred=self.linear(x)
        return y_pred

model=LinearModel()
# def layer_summary(model,x):
#     print("input shape:",x.size())
#     for name,layer in model.named_children():
#         x=layer(x)
#         print(f"{name:<20s} {'out shape':>20s}",x.size())
# layer_summary(model,x_data)
# sys.exit()
# 创建一个均方误差损失函数对象,该对象用于衡量模型预测值与真实值之间的差异  
criterion=torch.nn.MSELoss(size_average=False)
# 创建一个随机梯度下降优化器对象,该对象用于更新模型的参数。这里的学习率被设置为0.01
optimizer=torch.optim.SGD(model.parameters(),lr=0.01)

loss_list=[]
epoches=20
for epoch in range(epoches+1):
    y_pred=model(x_data)

    loss=criterion(y_pred,y_data)

    loss_list.append(loss.detach().numpy())
    # print(epoch,loss.item())
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
print("w=",model.linear.weight.item())
print("b=",model.linear.bias.item())

x_test=torch.Tensor([[4.0]])
y_test=model(x_test)
print("y_pred=",y_test.data)

import matplotlib.pyplot as plt

fig,axes=plt.subplots(nrows=1,ncols=2)
axes[0].plot(np.arange(0,epoches+1,1),loss_list)
axes[0].set_xlabel("epoches")
axes[0].set_ylabel("loss")
axes[0].legend()

# (3,1),因为y_pred有梯度,不能直接numpy()
y_pred=model(x_data).detach().numpy()
x_data=x_data.numpy()
y_data=y_data.numpy()

axes[1].scatter(x_data[:,0],y_data[:,0],color="blue",s=100,label="real data")
axes[1].plot(x_data[:,0],y_pred[:,0],color="orange",label="linear model")
axes[1].set_xlabel("x_data")
axes[1].set_ylabel("y_data")
axes[1].legend()

plt.show()

 插曲:跟踪数据在网络中的形状变化

model=LinearModel()
def layer_summary(model,x):
    print("input shape:",x.size())
    for name,layer in model.named_children():
        x=layer(x)
        print(f"{name:<20s} {'out shape':>20s}",x.size())
layer_summary(model,x_data)
input shape: torch.Size([3, 1])
linear                          out shape torch.Size([3, 1])

6.Logistic回归

import torch.nn.functional as F
import torch
import sys

x_data=torch.Tensor([[1.0],
                     [2.0],
                     [3.0]])
y_data=torch.Tensor([[0],
                     [0],
                     [1]])

class LogisticRegression(torch.nn.Module):
    def __init__(self) :
        super(LogisticRegression,self).__init__()
        self.linear=torch.nn.Linear(1,1)
    def forward(self,x):
        y_pred=torch.sigmoid(self.linear(x))
        return y_pred
    
model=LogisticRegression()

# BCE(y,p)=-[y*log(p) + (1-y)*log(1-p)]
criterion=torch.nn.BCELoss(size_average=False)
optimizer=torch.optim.SGD(model.parameters(),lr=0.01)

epoches=1000
for epoch in range(epoches+1):
    y_pred=model(x_data)
    loss=criterion(y_pred,y_data)
    print(epoch,loss.item())

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

import numpy as np
import matplotlib.pyplot as plt
#生成一个包含200个元素的一维数组x,该数组的元素是0到10之间均匀分布的数字
x=np.linspace(0,10,200)
#view()相当于reshape()
x_t=torch.Tensor(x).view((200,1))
y_t=model(x_t)
y=y_t.data.numpy()
plt.plot(x,y)
plt.plot([0,10],[0.5,0.5],c='r')
plt.xlabel("Hours")
plt.ylabel("Porbability of Pass")
plt.grid()
plt.show()

 

7.处理多维特征的输入

import torch
class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.linear=torch.nn.Linear(8,1)
        self.sigmoid=torch.nn.Sigmoid()

    def forward(self,x):
        x=self.sigmoid(self.linear(x))
        return x
model=Model()

import numpy as np
xy=np.loadtxt("diabetes.csv.gz",delimiter=",",dtype=np.float32)
x_data=torch.from_numpy(xy[:,:-1])
# 为了保存y_data的形状[32,1]的二维矩阵,而不是[32],所以不是xy[:,-1]
y_data=torch.from_numpy(xy[:,[-1]])

criterioin=torch.nn.BCELoss(size_average=True)

optimizer=torch.optim.SGD(model.parameters(),lr=0.1)

for epoch in range(100):
    y_pred=model(x_data)
    loss=criterioin(y_pred,y_data)

    #Backward()
    optimizer.zero_grad()
    loss.backward()

    #update
    optimizer.step()

8.加载数据集

8.1使用dataloader加载数据


"""使用dataloader加载数据"""
import torch
import numpy as np
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
import sys

#Dataset是抽象类
class DiabetesDataset(Dataset):
    def __init__(self,filePath):
        xy=np.loadtxt(filePath,delimiter=",",dtype=np.float32)
        self.x_data=torch.from_numpy(xy[:,:-1])
        #为了保存y_data的形状[32,1]的二维矩阵,而不是[32],所以不是xy[:,-1]
        self.y_data=torch.from_numpy(xy[:,[-1]])
        self.len=xy.shape[0]

    #magic function:dataset[index]获取数据
    def __getitem__(self, index): 
        return self.x_data[index],self.y_data[index]
    #magic function
    def __len__(self):
        return self.len

dataset=DiabetesDataset("diabetes.csv.gz")
train_loader=DataLoader(dataset=dataset,
                        batch_size=32,
                        shuffle=True,
                        num_workers=0)

class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.linear1=torch.nn.Linear(8,6)
        self.linear2=torch.nn.Linear(6,4)
        self.linear3=torch.nn.Linear(4,1)
        self.sigmoid=torch.nn.Sigmoid()

    def forward(self,x):
        x=self.sigmoid(self.linear1(x))
        x=self.sigmoid(self.linear2(x))
        x=self.sigmoid(self.linear3(x))
        return x
    
model=Model()

criterion=torch.nn.BCELoss(reduction="mean")
optimizer=torch.optim.SGD(model.parameters(),lr=0.01)

def train():
    for epoch in range(20):
        #enumerate 从 0 开始枚举 train_loader 中的数据
        for i, data in enumerate(train_loader,0):
            # inputs_tensor([32,8]),labels_tensor([32,1])
            inputs,labels=data

            y_pred=model(inputs)
            loss=criterion(y_pred,labels)
            print(f"epoch={epoch}, i={i}, loss={loss.item()}")

            optimizer.zero_grad()
            loss.backward()

            optimizer.step()
train()

8.2 enumerate(train_loader) 一次迭代的结构

for a in enumerate(train_loader,0):
    print(type(a))  # turple
    print(len(a))   # len==2
    
    print(type(a[0]),type(a[1]))#int  list
    print(len(a[1]))   #len==2

    print(type(a[1][0]),type(a[1][1])) # tensor tensor
    print(a[1][0].size(),a[1][1].size()) #([32,8]), (32,1)
    break
sys.exit()

"""
a的结构
a==turple:(

   int:index of batch,

   list:[ tensor([32,8]):inputs , tensor([32,1]):labels ] 
)
"""

9.多分类问题

9.1 torch.max()的例子

import torch
"""
一个torch.max的例子
"""
# Example predicted outputs (scores)
outputs = torch.tensor([
    [0.1, 0.8, 0.3],   # Sample 1: Scores for classes 0, 1, 2
    [0.4, 0.2, 0.9],   # Sample 2: Scores for classes 0, 1, 2
    [0.7, 0.6, 0.5],   # Sample 3: Scores for classes 0, 1, 2
    [0.2, 0.3, 0.5]    # Sample 4: Scores for classes 0, 1, 2
])

# Using torch.max to get the index of the maximum value along dimension 1 (column-wise)
number,predicted_indices = torch.max(outputs, dim=1)

# number:  tensor([0.8000, 0.9000, 0.7000, 0.5000])
print("number: ",number) 
# Predicted indices: tensor([1, 2, 0, 2])
print("Predicted indices:", predicted_indices)

9.1 矩阵在网络中的计算中的,形状变化 

import torch 
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
import random
import matplotlib.pyplot as plt

import sys


class Net(torch.nn.Module):
    def __init__(self) -> None:
        super(Net,self).__init__()
        self.layer1=torch.nn.Linear(784,512)
        self.layer2=torch.nn.Linear(512,256)
        self.layer3=torch.nn.Linear(256,128)
        self.layer4=torch.nn.Linear(128,64)
        self.layer5=torch.nn.Linear(64,10)
    def forward(self,x):
        x=x.view(-1,784)
        x=F.relu(self.layer1(x))
        x=F.relu(self.layer2(x))
        x=F.relu(self.layer3(x))
        x=F.relu(self.layer4(x))
        x=self.layer5(x)
        return x
    
model=Net()
"""
变量的变化形状变化过程
"""
def layer_summary(model,x):
    print("input shape:",x.size())
    x=x.view(-1,784)
    print("input shape:",x.size())
    for name,layer in model.named_children():
        x=layer(x)
        print(f"{name:<20s} {'out shape':>20s}",x.size())
# 看网络的内部结构
print(model)
x_data=torch.randn(1,1,28,28)
layer_summary(model,x_data)

9.2 使用全连接网络训练MNIST数据集 

import torch 
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
import random
import matplotlib.pyplot as plt

import sys

batchSize=64
transform=transforms.Compose([
    transforms.ToTensor(),
    #均值=0.1307,标准差=0.
    # output=(input-mean)/std
    transforms.Normalize((0.1307,),(0.3081,))
])
train_dataset=datasets.MNIST(root="data/mnist",
                          train=True,
                          download=True,
                          transform=transform)
train_loader=DataLoader(train_dataset,
                        shuffle=True,
                        batch_size=batchSize)

test_dataset=datasets.MNIST(root="data/mnist",
                          train=False,
                          download=True,
                          transform=transform)
test_loader=DataLoader(test_dataset,
                        shuffle=True,
                        batch_size=batchSize)

def showRandomPictures(train_loader):
    data_iter=iter(train_loader)
    images,labels=data_iter.__next__()
    # Choose a random index from the batch
    random_index = random.randint(0, batchSize - 1)

    # Display the transformed image
    transformed_image = images[random_index].squeeze().numpy()
    transformed_image = (transformed_image * 0.3081) + 0.1307  # Inverse normalization
    plt.imshow(transformed_image, cmap='gray')  # Assuming MNIST images are grayscale
    plt.title(f"Label: {labels[random_index].item()}")
    plt.show() 
# showRandomPictures(train_loader)

class Net(torch.nn.Module):
    def __init__(self) -> None:
        super(Net,self).__init__()
        self.layer1=torch.nn.Linear(784,512)
        self.layer2=torch.nn.Linear(512,256)
        self.layer3=torch.nn.Linear(256,128)
        self.layer4=torch.nn.Linear(128,64)
        self.layer5=torch.nn.Linear(64,10)
    def forward(self,x):
        x=x.view(-1,784)
        x=F.relu(self.layer1(x))
        x=F.relu(self.layer2(x))
        x=F.relu(self.layer3(x))
        x=F.relu(self.layer4(x))
        x=self.layer5(x)
        return x
    
model=Net()

"""
input shape: torch.Size([1, 1, 28, 28])
input shape: torch.Size([1, 784])
layer1                          out shape torch.Size([1, 512])
layer2                          out shape torch.Size([1, 256])
layer3                          out shape torch.Size([1, 128])
layer4                          out shape torch.Size([1, 64]) 
layer5                          out shape torch.Size([1, 10]) 
"""
# def layer_summary(model,x):
#     print("input shape:",x.size())
#     x=x.view(-1,784)
#     print("input shape:",x.size())
#     for name,layer in model.named_children():
#         x=layer(x)
#         print(f"{name:<20s} {'out shape':>20s}",x.size())
# x_data=torch.randn(1,1,28,28)
# layer_summary(model,x_data)




criterion=torch.nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)

device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

def train(epoch):
    running_loss=0.0
    for batch_idx,data in enumerate(train_loader,0):
        # inputs_Size([64,1,28,28])
        # target_Size([64])
        inputs,target=data
        inputs=inputs.to(device)
        target=target.to(device)

        optimizer.zero_grad()
        # output_size([64,10])
        outputs=model(inputs)

        # loss=tensor(2.3112,grad_fn=<NllLossBackward0>)
        # loss.item()=2.3112
        # loss.size()=[],因为loss是个标量,不是矩阵或者张量或者矢量
        loss=criterion(outputs,target)
        loss.backward()
        optimizer.step()

        running_loss+=loss.item()
        if batch_idx%300==299:
            print(f"[epoch={epoch+1}, batch_index={batch_idx+1}, training_loss={running_loss/300}]")
            running_loss=0.0

accuracyHistory=[]
def test():
    correct=0
    total=0
    with torch.no_grad():
        for data in test_loader:
            #imagesSize([64,1,28,28]) lableSize([64])
            images,labels=data
            images=images.to(device)
            labels=labels.to(device)

            # outputsSize([64,10])
            outputs=model(images)

            #每一行的最大值的下标[max,maxIndex]
            _,predicted=torch.max(outputs.data,dim=1)
            #label.size(0)是batch_size
            total+=labels.size(0)
            correct+=(predicted==labels).sum().item()
    print(f"Accuracy on test set:{100*correct/total}")
    accuracyHistory.append(100*correct/total)

if __name__=="__main__":
    for epoch in range(10):
        train(epoch)
        test()
    plt.plot(accuracyHistory)
    plt.xlabel("epoches")
    plt.ylabel("accuracy in testset")
    plt.show()

 

10.卷积神经网络

10.1 一个卷积层

import torch
in_channels, out_channels= 5, 10
width, height = 100, 100
kernel_size = 3
batch_size = 1
input = torch.randn(batch_size,
                    in_channels,
                    width, 
                    height)



conv_layer = torch.nn.Conv2d(in_channels,
                            out_channels,
                            kernel_size=kernel_size)
output = conv_layer(input)
print(input.shape)  # torch.Size[1,5,100,100]
print(output.shape) # torch.Size[1,10,98,98]
# conv_layer.weight.data.shape[out_channels,in_channels,kernel_height,kernel_width]
print(conv_layer.weight.shape) # torch.([10,5,3,3])
# print(conv_layer.weight.data)
"""
input[bs,channels,h,w]
output[bs,channels's, h-k+1,w-k+1]
"""

10.2 有padding的卷积层

import torch
input =  [  3,4,6,5,7,
            2,4,6,8,2,
            1,6,7,8,4,
            9,7,4,6,2,
            3,7,5,4,1   ]
input = torch.Tensor(input).view(1, 1, 5, 5)
conv_layer = torch.nn.Conv2d(1, 1, kernel_size=3, padding=1, bias=False)
kernel = torch.Tensor([1,2,3,4,5,6,7,8,9]).view(1, 1, 3, 3)
print(kernel)
conv_layer.weight.data = kernel.data
output = conv_layer(input)
print(output)
print(output.shape)

10.3 Maxpooling

import torch
input = [   3,4,6,5,
            2,4,6,8,
            1,6,7,8,
            9,7,4,6,
        ]
input = torch.Tensor(input).view(1, 1, 4, 4)
maxpooling_layer = torch.nn.MaxPool2d(kernel_size=2)
output = maxpooling_layer(input)
print(output)

10.4 在自定义卷积矩阵在网络中的变化 

import torch 
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
import random
import matplotlib.pyplot as plt

import sys


class Net(torch.nn.Module):
    def __init__(self) :
        super(Net,self).__init__()
        self.conv1=torch.nn.Conv2d(1,10,kernel_size=5)
        self.pooling1=torch.nn.MaxPool2d(2)
        self.conv2=torch.nn.Conv2d(10,20,kernel_size=5)
        self.pooling2=torch.nn.MaxPool2d(2)
        self.fc=torch.nn.Linear(320,10)
    
    def forward(self,x):
        batch_size=x.size(0)
        x=F.relu(self.pooling1(self.conv1(x)))
        x=F.relu(self.pooling2(self.conv2(x)))
        x=x.view(batch_size,-1)
        x=self.fc(x)
        return x
    
model=Net()
"""
变量的变化形状变化过程
"""
def layer_summary(model,x):
    for name,layer in model.named_children():
        x=layer(x)
        print(f"{name:<20s} {'out shape':>20s}",x.size())
        if name=="pooling2":
            bs=x.size(0)
            x=x.view(bs,-1)
# 看网络的内部结构
print(model)
# x_data[bat_size:64, channels:1, height:28, width:28]
x_data=torch.randn(64,1,28,28)
layer_summary(model,x_data)

"""
result:
Net(
  (conv1): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1))
  (pooling1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (conv2): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1))
  (pooling2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (fc): Linear(in_features=320, out_features=10, bias=True)
)
conv1                           out shape torch.Size([64, 10, 24, 24])
pooling1                        out shape torch.Size([64, 10, 12, 12])
conv2                           out shape torch.Size([64, 20, 8, 8])  
pooling2                        out shape torch.Size([64, 20, 4, 4])  
fc                              out shape torch.Size([64, 10]) 
"""

10.5 构建CNN网络检测MNIST数据集 

import torch 
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
import random
import matplotlib.pyplot as plt
import sys

batchSize=64
transform=transforms.Compose([
    transforms.ToTensor(),
    #均值=0.1307,标准差=0.3081
    transforms.Normalize((0.1307,),(0.3081,))
])
train_dataset=datasets.MNIST(root="data/mnist",
                          train=True,
                          download=True,
                          transform=transform)
train_loader=DataLoader(train_dataset,
                        shuffle=True,
                        batch_size=batchSize)

test_dataset=datasets.MNIST(root="data/mnist",
                          train=False,
                          download=True,
                          transform=transform)
test_loader=DataLoader(test_dataset,
                        shuffle=True,
                        batch_size=batchSize)

def showRandomPictures(train_loader):
    data_iter=iter(train_loader)
    images,labels=data_iter.__next__()

    # Choose a random index from the batch
    random_index = random.randint(0, batchSize - 1)

    # Display the transformed image
    transformed_image = images[random_index].squeeze().numpy()
    transformed_image = (transformed_image * 0.3081) + 0.1307  # Inverse normalization
    plt.imshow(transformed_image, cmap='gray')  # Assuming MNIST images are grayscale
    plt.title(f"Label: {labels[random_index].item()}")
    plt.show() 
showRandomPictures(train_loader)



class Net(torch.nn.Module):
    def __init__(self) :
        super(Net,self).__init__()
        self.conv1=torch.nn.Conv2d(1,10,kernel_size=5)
        self.conv2=torch.nn.Conv2d(10,20,kernel_size=5)
        self.pooling=torch.nn.MaxPool2d(2)
        self.fc=torch.nn.Linear(320,10)
    
    """
    image[bs,1,28*28]---conv1--->[bs,10,24*24]--->maxpooling--->[bs,10,12*12]
    --->conv2--->image[bs,20,8*8]---maxpooling--->
    image[bs,20,4*4]---view--->image[bs,320]-->linear-->image[bs,10]
    """
    def forward(self,x):
        batch_size=x.size(0)
        x=F.relu(self.pooling(self.conv1(x)))
        x=F.relu(self.pooling(self.conv2(x)))
        x=x.view(batch_size,-1)
        x=self.fc(x)
        return x
    
model=Net()
device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
criterion=torch.nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)


def train(epoch):
    running_loss=0.0
    for batch_idx,data in enumerate(train_loader,0):
        inputs,target=data
        # inputSize[64,1,28,28],targetSize([64])
        inputs,target=inputs.to(device),target.to(device)
        optimizer.zero_grad()
        # outputSize[64,10]
        ouputs=model(inputs)
        # loss(2,3810,device="cuda:0",grad_fn=<NllLossBackward0>)
        loss=criterion(ouputs,target)
        loss.backward()
        optimizer.step()

        running_loss+=loss.item()
        if batch_idx%300==299:
            print("[%d %5d] loss:%.3f"%(epoch+1,batch_idx+1,running_loss/2000))
            running_loss=0.0
accuracyHistory=[]
def test():
    correct=0
    total=0
    with torch.no_grad():
        for data in test_loader:
            # inputsSize[64,1,28,28], targetSize[64]
            inputs,target=data
            inputs,target=inputs.to(device),target.to(device)
            # outputSize[64,10]
            outputs=model(inputs)
            # predicted[64]
            _,predicted=torch.max(outputs.data,dim=1)
            total+=target.size(0)
            correct+=(predicted==target).sum().item()

            print(inputs.size()," ",target.size())
            print(outputs.size())
            print(predicted.size())
            sys.exit()

    print("Accuracy on test set %d %% [%d/%d]"%(100*correct/total,correct,total))
    accuracyHistory.append(100 * correct/total)


if __name__=="__main__":
    for epoch in range(10):
        train(epoch)
        test()
    plt.plot(accuracyHistory)
    plt.xlabel("epoches")
    plt.ylabel("accuracy in testset")
    plt.show()

11. inception 

11.1 inceptionA:一个inception模块

"""
transfor image(batch,c,w,h)-->image(batch,88,,w,h)
"""
import torch
from torch import nn
import torch.nn.functional as F
"""
MNIST数据集中,每张图片(c:1,h:28,w:28)
"""
class InceptionA(nn.Module):
    def __init__(self,in_channel) -> None:
        super(InceptionA,self).__init__()

        self.branch_pool1x1=nn.Conv2d(in_channel,24,kernel_size=1)

        self.branch1x1=nn.Conv2d(in_channel,16,kernel_size=1)
        
        self.branch5x5_1=nn.Conv2d(in_channel,16,kernel_size=1)
        self.branch5x5_2=nn.Conv2d(16,24,kernel_size=5,padding=2)

        self.branch3x3_1=nn.Conv2d(in_channel,16,kernel_size=1)
        self.branch3x3_2=nn.Conv2d(16,24,kernel_size=3,padding=1)
        self.branch3x3_3=nn.Conv2d(24,24,kernel_size=3,padding=1)

    def forward(self,x):
        branch_pool=F.avg_pool2d(x,kernel_size=3,stride=1,padding=1)
        branch_pool=self.branch_pool1x1(branch_pool)

        branch1x1=self.branch1x1(x)

        branch5x5=self.branch5x5_1(x)
        branch5x5=self.branch5x5_2(branch5x5)

        branch3x3=self.branch3x3_1(x)
        branch3x3=self.branch3x3_2(branch3x3)
        branch3x3=self.branch3x3_3(branch3x3)

        outputs=[branch1x1,branch5x5,branch3x3,branch_pool]

        return torch.cat(outputs,dim=1)

11.2 inceptionA2 整个网络

"""
the overall Network
"""
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader

import torch.optim as optim
import random
import matplotlib.pyplot as plt

import torch 
import torch.nn
from torch import nn
import torch.nn.functional as F
import sys
"""
InceptionA:transfor image(batch,c,w,h)-->image(batch,88,,w,h)
"""
from InceptionA import InceptionA


class Net(nn.Module):
    def __init__(self) -> None:
        super(Net,self).__init__()
        self.conv1=nn.Conv2d(1,10,kernel_size=5)
        self.conv2=nn.Conv2d(88,20,kernel_size=5)

        self.incep1=InceptionA(in_channel=10)
        self.incep2=InceptionA(in_channel=20)

        self.maxpooling=nn.MaxPool2d(2)
        self.fc=nn.Linear(1408,10)

    def forward(self,x):
        batchSize=x.size(0)
        x=F.relu(self.maxpooling(self.conv1(x)))
        x=self.incep1(x)
        x=F.relu(self.maxpooling(self.conv2(x)))
        x=self.incep2(x)
        x=x.view(batchSize,-1)
        x=self.fc(x)
        return x

11.3 inceptionA3 设计train和test过程

"""
data:MiNST
The concrete training and testing procedure
"""
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader

import torch.optim as optim
import random
import matplotlib.pyplot as plt

import torch 
import torch.nn
from torch import nn
import torch.nn.functional as F

from InceptionA2 import Net

batchSize=64
transformSetting=transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,),(0.3081,))
])
"""
prepare the traning and testing data
"""
train_dataset=datasets.MNIST(root="data/mnist",
                             train=True,
                             download=True,
                             transform=transformSetting)
train_loader=DataLoader(train_dataset,
                        shuffle=True,
                        batch_size=batchSize)

test_dataset=datasets.MNIST(root="data/mnist",
                            train=False,
                            download=True,
                            transform=transformSetting)
test_loader=DataLoader(test_dataset,
                       shuffle=True,
                       batch_size=batchSize)

def showRandomPictures(train_loader):
    data_iter=iter(train_loader)
    images,labels=data_iter.__next__()

    # Choose a random index from the batch
    random_index = random.randint(0, batchSize - 1)

    # Display the transformed image
    transformed_image = images[random_index].squeeze().numpy()
    transformed_image = (transformed_image * 0.3081) + 0.1307  # Inverse normalization
    plt.imshow(transformed_image, cmap='gray')  # Assuming MNIST images are grayscale
    plt.title(f"Label: {labels[random_index].item()}")
    plt.show() 
showRandomPictures(train_loader)

model=Net()
device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
criterion=torch.nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)

def train(epoch):
    running_loss=0.0
    for batch_idx,data in enumerate(train_loader,0):
        inputs,target=data
        inputs,target=inputs.to(device),target.to(device)
        optimizer.zero_grad()

        ouputs=model(inputs)
        loss=criterion(ouputs,target)
        loss.backward()
        optimizer.step()

        running_loss+=loss.item()
        if batch_idx%300==299:
            print("[%d %5d] loss:%.3f"%(epoch+1,batch_idx+1,running_loss/2000))
            running_loss=0.0

accuracyOnTestHistory=[]
def test():
    correct=0
    total=0
    with torch.no_grad():
        for data in test_loader:
            inputs,target=data
            inputs,target=inputs.to(device),target.to(device)

            outputs=model(inputs)
            #每一行的最大值的下标[max,maxIndex]
            _,predicted=torch.max(outputs.data,dim=1)

            total+=target.size(0)
            correct+=(predicted==target).sum().item()
    print("Accuracy on test set %d %%[%d/%d]"%(100*correct/total,correct,total))
    accuracyOnTestHistory.append(100*correct/total)

if __name__=="__main__":
    for epoch in range(10):
        train(epoch)
        test()
    plt.plot(accuracyOnTestHistory)
    plt.show()

12. ResNet

12.1 ResNet :一个残差单元

"""
一个残差单元
"""

import torch
from torch import nn
import torch.nn.functional as F
"""
image(c,w,h)--->image(c,w,h)
"""
class ResidualBlock(nn.Module):
    def __init__(self, channels) :
        super(ResidualBlock,self).__init__()
        self.channels=channels
        self.conv1=nn.Conv2d(channels,channels,
                             kernel_size=3,padding=1)
        self.conv2=nn.Conv2d(channels,channels,
                             kernel_size=3,padding=1)
    def forward(self,x):
        y=F.relu(self.conv1(x))
        y=self.conv2(y)
        return F.relu(x+y)

12.2 ResNet2 :整个网络

import torch 
from torch import nn
from Residual import ResidualBlock
import torch.nn.functional as F
class Net(nn.Module):
    def __init__(self) -> None:
        super(Net,self).__init__()
        self.conv1=nn.Conv2d(1,16,kernel_size=5)
        self.conv2=nn.Conv2d(16,32,kernel_size=5)
        self.mp=nn.MaxPool2d(2)

        self.residualBock1=ResidualBlock(16)
        self.residualBock2=ResidualBlock(32)

        self.fc=nn.Linear(512,10)

    def forward(self,x):
        batch=x.size(0)
        x=self.mp(F.relu(self.conv1(x)))
        x=self.residualBock1(x)
        x=self.mp(F.relu(self.conv2(x)))
        x=self.residualBock2(x)
        x=x.view(batch,-1)
        x=self.fc(x)
        return x

12.3 ResNet3 设计train和test过程

from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader

import torch.optim as optim
import random
import matplotlib.pyplot as plt

import torch 
import torch.nn
from torch import nn
import torch.nn.functional as F

from Residual2 import Net

batchSize=64
transformSetting=transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,),(0.3081,))
])
"""
prepare the traning and testing data
"""
train_dataset=datasets.MNIST(root="data/mnist",
                             train=True,
                             download=True,
                             transform=transformSetting)
train_loader=DataLoader(train_dataset,
                        shuffle=True,
                        batch_size=batchSize)

test_dataset=datasets.MNIST(root="data/mnist",
                            train=False,
                            download=True,
                            transform=transformSetting)
test_loader=DataLoader(test_dataset,
                       shuffle=True,
                       batch_size=batchSize)

def showRandomPictures(train_loader):
    data_iter=iter(train_loader)
    images,labels=data_iter.__next__()

    # Choose a random index from the batch
    random_index = random.randint(0, batchSize - 1)

    # Display the transformed image
    transformed_image = images[random_index].squeeze().numpy()
    transformed_image = (transformed_image * 0.3081) + 0.1307  # Inverse normalization
    plt.imshow(transformed_image, cmap='gray')  # Assuming MNIST images are grayscale
    plt.title(f"Label: {labels[random_index].item()}")
    plt.show() 
showRandomPictures(train_loader)

model=Net()
device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
criterion=torch.nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)

def train(epoch):
    running_loss=0.0
    for batch_idx,data in enumerate(train_loader,0):
        inputs,target=data
        inputs,target=inputs.to(device),target.to(device)
        optimizer.zero_grad()

        ouputs=model(inputs)
        loss=criterion(ouputs,target)
        loss.backward()
        optimizer.step()

        running_loss+=loss.item()
        if batch_idx%300==299:
            print("[%d %5d] loss:%.3f"%(epoch+1,batch_idx+1,running_loss/2000))
            running_loss=0.0

accuracy_testset_history=[]
def test():
    correct=0
    total=0
    with torch.no_grad():
        for data in test_loader:
            inputs,target=data
            inputs,target=inputs.to(device),target.to(device)

            outputs=model(inputs)
            #每一行的最大值的下标[max,maxIndex]
            _,predicted=torch.max(outputs.data,dim=1)

            total+=target.size(0)
            correct+=(predicted==target).sum().item()
    print("Accuracy on test set %d %%[%d/%d]"%(100*correct/total,correct,total))
    accuracy_testset_history.append(100*correct/total)

if __name__=="__main__":
    for epoch in range(10):
        train(epoch)
        test()
    plt.plot(accuracy_testset_history)
    plt.show()

13. RNN

 敬请期待

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值