参考《Python深度学习》目录如下:
配置相关环境,下载pytorch,这一天就这样结束了。
import torchvision as tv
import torch as t
import torchvision.transforms as transforms
from torchvision.transforms import ToPILImage
# torchvision是pytorch的一个图形库,它服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。以下是torchvision的构成:
# torchvision.datasets: 一些加载数据的函数及常用的数据集接口;
# torchvision.models: 包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;
# torchvision.transforms: 常用的图片变换,例如裁剪、旋转等;
# torchvision.utils: 其他的一些有用的方法。
show = ToPILImage()
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
# torchvision.transforms主要是用于常见的一些图形变换。
# torchvision.transforms.Compose()类。这个类的主要作用是串联多个图片变换的操作。
# transforms.ToTensor()可以将PIL和numpy格式的数据从[0,255]范围转换到[0,1] ,具体做法其实就是将原始数据除以255。
# 另外原始数据的shape是(H x W x C),通过transforms.ToTensor()后shape会变为(C x H x W)。
# 我们通过前面的ToTensor已经将数据归一化到了0-1之间,现在又接上了一个Normalize函数有什么用呢?
# 其实Normalize函数做的是将数据变换到了[-1,1]之间。之前的数据为0-1,当取0时,output =(0 - 0.5)/ 0.5 = -1;当取1时,
# output =(1 - 0.5)/ 0.5 = 1。这样就把数据统一到了[-1,1]之间了,那么问题又来了,数据统一到[-1,1]有什么好处呢?
# 数据如果分布在(0,1)之间,可能实际的bias,就是神经网络的输入b会比较大,而模型初始化时b=0的,这样会导致神经网络收敛比较慢,
# 经过Normalize后,可以加快模型的收敛速度。
trainset = tv.datasets.CIFAR10(root='./data',train=True,download=True,transform=transform)
# CIFAR-10 是由 Hinton 的学生 Alex Krizhevsky 和 Ilya Sutskever 整理的一个用于识别普适物体的小型数据集。
# 一共包含 10 个类别的 RGB 彩色图 片:飞机( airplane )、汽车( automobile )、鸟类( bird )、猫( cat )、
# 鹿( deer )、狗( dog )、蛙类( frog )、马( horse )、船( ship )和卡车( truck )。图片的尺寸为 32×32 ,
# 数据集中一共有 50000 张训练图片和 10000 张测试图片。
# CIFAR10中参数 root=数据放在哪。 train=是否为训练集 。 download=是否去网上下载。里面的那个 transform 就是转换数据类型为Tensor类型。
trainloard =t.utils.data.DataLoader(trainset,batch_size = 64,shuffle=True,num_workers=2)
# Dataset只负责数据的抽取,调用一次__getitem__()只返回一个样本。如果希望批处理,还要同时进行shuffle和并行加速等操作,
# 就需要使用DataLoader。
# datatset:加载的数据集。
# batch_size:批大小。
# shuffle:是否将数据打乱,一般训练集的时候需要打乱,而测试集的时候则不需要进行打乱。
# sampler:样本抽样。
# num_workers:使用多进程加载的进程数,0代表不使用多进程。
testset = tv.datasets.CIFAR10(root='./data',train=False,download=True,transform=transform)
testloard =t.utils.data.DataLoader(testset,batch_size = 64,shuffle=False,num_workers=2)
classes = ('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')
# (data,label) = trainset[100]
# print(classes[label])
# show((data+1)/2).resize((100,100))
# 不加.show()无法显示图片
# dataiter = iter(trainloard)
# images,labels = dataiter.next()
# print(' '.join('%11s'%classes[labels[j]] for j in range(4)))
# show(tv.utils.make_grid((images+1)/2)).resize((400,100))
关键词:Numpy
参考书籍:《Python深度学习-基于pytorch》
def func_arange_linspace():
# arange([start,]stop[,step,],dtype=None)
# start 起始位置 stop 结束位置 step 步长
print(np.arange(10))
print(np.arange(0,10))
print(np.arange(1,4,0.5))
print(np.arange(9,-1,-1))
# linspace(start,stop,num=50,endpoint=True,restep=False,dtype=None)
# num 表示等分数量 endpoint 表示是否包含终点 restep 表示是否返回步长
print(np.linspace(0,1,10))
def func_multiply():
# np.multiply(x1,x2,/,out=None,*,where=True,casting='same_kind',order='K',dtype=None,subok=True[,signature,extobj])
A = np.array([[1,2],[-1,4]])
B = np.array(([[2,0],[3,4]]))
C = A*B
print(C)
def func_dot():
X1 = np.array([[1,2],[3,4]])
X2 = np.array([[5,6,7],[8,9,10]])
# 线性代数 两个矩阵相乘 此处为2X2的矩阵与2X3的矩阵相乘
X3 = np.dot(X1,X2)
print(X3)
import numpy as np
# Numpy 封装了 一个新的ndarray对象,它是一个多维数组对象。封装了许多常用的数学运算符
def trans_list_ndarray():
lst1 = [3.14,2.17,0,1,2]
ndl = np.array(lst1)
# Numpy 中的array将list转换成ndarray
print(ndl)
print(type(ndl))
lst2 = [[3.14,2.17,0,1,2],[1,2,3,4,5]]
nd2 = np.array(lst2)
# 嵌套列表也可以转换成ndarray
print(nd2)
print(type(nd2))
def func_random():
nd3 = np.random.random([3,3])
print(nd3)
print("nd3的形状为:",nd3.shape)
# 为了每次能够生成同一份数据 可以指定一个随机种子 使用shuffle函数打乱生成的随机数
np.random.seed(123)
# 指定种子
nd4 = np.random.randn(2,3)
print(nd4)
np.random.shuffle(nd4)
print("随机打乱后数据:")
print(nd4)
print(type(nd4))
def func_arange_linspace():
# arange([start,]stop[,step,],dtype=None)
# start 起始位置 stop 结束位置 step 步长
print(np.arange(10))
print(np.arange(0,10))
print(np.arange(1,4,0.5))
print(np.arange(9,-1,-1))
# linspace(start,stop,num=50,endpoint=True,restep=False,dtype=None)
# num 表示等分数量 endpoint 表示是否包含终点 restep 表示是否返回步长
print(np.linspace(0,1,10))
def func_multiply():
# np.multiply(x1,x2,/,out=None,*,where=True,casting='same_kind',order='K',dtype=None,subok=True[,signature,extobj])
A = np.array([[1,2],[-1,4]])
B = np.array(([[2,0],[3,4]]))
C = A*B
print(C)
def func_dot():
X1 = np.array([[1,2],[3,4]])
X2 = np.array([[5,6,7],[8,9,10]])
# 线性代数 两个矩阵相乘 此处为2X2的矩阵与2X3的矩阵相乘
X3 = np.dot(X1,X2)
print(X3)
def func_batch():
data_train = np.random.randn(10000,2,3)
print(data_train.shape)
np.random.shuffle(data_train)
# 打乱数据集顺序
batch_size =100
for i in range(0,len(data_train),batch_size):
x_batch_sum = np.sum(data_train[i:i+batch_size])
print("第{}批次,该批次的数据之后:{}".format(i,x_batch_sum))
def func_broadcast():
A = np.arange(0,40,10).reshape(4,1)
B = np.arange(0,3)
C = A + B
print(C)
if __name__ == '__main__':
# trans_list_ndarray()
# func_random()
# func_arange_linspace()
# func_multiply()
# func_dot()
# func_batch()
func_broadcast()
pass
def numpy_learn():
# 1、生成输入数据x及目标数据y
np.random.seed(100)
x = np.linspace(-1,1,100).reshape(100,1)
# linspace(start,end,steps) start起点 end终点 step分成多少份
print(x.size)
y = 3*np.power(x,2) + 2 + 0.2*np.random.rand(x.size).reshape(100,1)
# np.power(x,2)为x平方 0.2*np.random……表示加上一些噪音数据
# plt.scatter(x,y)
# 2、对x y进行描点
# plt.show()
# 3、初始化权重参数
w1 = np.random.rand(1,1)
# random.rand(1,1) 生成1行1列的数(生成的数在0~1之间)
b1 = np.random.rand(1,1)
# 4、训练模型
# 定义损失函数
lr = 0.001 # 学习率
for i in range(800):
y_pred = np.power(x,2)*w1 + b1
loss = 0.5 * (y_pred - y) ** 2
loss = loss.sum()
grad_w = np.sum((y_pred - y)*np.power(x,2))
grad_b = np.sum((y_pred - y))
w1 -= lr * grad_w
b1 -= lr * grad_b
plt.plot(x,y_pred,'r-',label='predict')
plt.scatter(x,y,color='blue',marker='o',label='true')
plt.xlim(-1,1)
plt.ylim(2,6)
plt.legend()
plt.show()
print(w1,b1)
def Tensor_learn():
t.manual_seed(100)
# 设置 CPU 生成随机数的 种子 ,方便下次复现实验结果
dtype = t.float
# 生成x坐标数据 x为tenor 需要把x的形状转换为100X1
x = t.unsqueeze(torch.linspace(-1,1,100),dim = 1)
y = 3*x.pow(2) + 2 + 0.2*torch.rand(x.size())
# plt.scatter(x.numpy(),y.numpy())
# plt.show()
# 初始化权重参数
# 随机初始化参数,参数w、b为需要学习的,故需要requires_grad=True
w = t.randn(1,1,dtype=dtype,requires_grad=True)
# t.randn()表示生成标准正态分布随机数(均值为1,标准差为1,数据类型)
b = t.randn(1,1,dtype=dtype,requires_grad=True)
# 训练模型
lr = 0.001 # 学习率
for ii in range(800):
y_pred = x.pow(2).mm(w) + b
# 表示x的平方与w相乘
loss = 0.5 * (y_pred - y) ** 2
loss = loss.sum()
# 自动计算梯度 梯度存放在grad属性中
loss.backward()
# 手动更新参数 需要用torch.no_grad(),使上下文环境中切断自动求导的计算
with t.no_grad():
w -= lr * w.grad
b -= lr * b.grad
w.grad.zero_()
b.grad.zero_()
plt.plot(x.numpy(), y_pred.detach().numpy(), 'r-', label='predict')
# 绘制连续图
plt.scatter(x.numpy(), y.numpy(), color='blue', marker='o', label='true')
# 绘制散点图
plt.xlim(-1, 1)
# 限制x的范围
plt.ylim(2, 6)
# 限制y的范围
plt.legend()
plt.show()
print(w, b)
import numpy as np
import torch
from matplotlib import pyplot as plt
import torch as t
def numpy_learn():
# 1、生成输入数据x及目标数据y
np.random.seed(100)
x = np.linspace(-1,1,100).reshape(100,1)
# linspace(start,end,steps) start起点 end终点 step分成多少份
print(x.size)
y = 3*np.power(x,2) + 2 + 0.2*np.random.rand(x.size).reshape(100,1)
# np.power(x,2)为x平方 0.2*np.random……表示加上一些噪音数据
# plt.scatter(x,y)
# 2、对x y进行描点
# plt.show()
# 3、初始化权重参数
w1 = np.random.rand(1,1)
# random.rand(1,1) 生成1行1列的数(生成的数在0~1之间)
b1 = np.random.rand(1,1)
# 4、训练模型
# 定义损失函数
lr = 0.001 # 学习率
for i in range(800):
y_pred = np.power(x,2)*w1 + b1
loss = 0.5 * (y_pred - y) ** 2
loss = loss.sum()
grad_w = np.sum((y_pred - y)*np.power(x,2))
grad_b = np.sum((y_pred - y))
w1 -= lr * grad_w
b1 -= lr * grad_b
plt.plot(x,y_pred,'r-',label='predict')
# 绘制连续图
plt.scatter(x,y,color='blue',marker='o',label='true')
# 绘制散点图
plt.xlim(-1,1)
# 限制x的范围
plt.ylim(2,6)
# 限制y的范围
plt.legend()
plt.show()
print(w1,b1)
def Tensor_learn():
t.manual_seed(100)
# 设置 CPU 生成随机数的 种子 ,方便下次复现实验结果
dtype = t.float
# 生成x坐标数据 x为tenor 需要把x的形状转换为100X1
x = t.unsqueeze(torch.linspace(-1,1,100),dim = 1)
y = 3*x.pow(2) + 2 + 0.2*torch.rand(x.size())
# plt.scatter(x.numpy(),y.numpy())
# plt.show()
# 初始化权重参数
# 随机初始化参数,参数w、b为需要学习的,故需要requires_grad=True
w = t.randn(1,1,dtype=dtype,requires_grad=True)
# t.randn()表示生成标准正态分布随机数(均值为1,标准差为1,数据类型)
b = t.randn(1,1,dtype=dtype,requires_grad=True)
# 训练模型
lr = 0.001 # 学习率
for ii in range(800):
y_pred = x.pow(2).mm(w) + b
# 表示x的平方与w相乘
loss = 0.5 * (y_pred - y) ** 2
loss = loss.sum()
# 自动计算梯度 梯度存放在grad属性中
loss.backward()
# 手动更新参数 需要用torch.no_grad(),使上下文环境中切断自动求导的计算
with t.no_grad():
w -= lr * w.grad
b -= lr * b.grad
w.grad.zero_()
b.grad.zero_()
plt.plot(x.numpy(), y_pred.detach().numpy(), 'r-', label='predict')
# 绘制连续图
plt.scatter(x.numpy(), y.numpy(), color='blue', marker='o', label='true')
# 绘制散点图
plt.xlim(-1, 1)
# 限制x的范围
plt.ylim(2, 6)
# 限制y的范围
plt.legend()
plt.show()
print(w, b)
if __name__ == '__main__':
# numpy_learn()
Tensor_learn()
pass
import numpy as np
import torch
from torchvision.datasets import mnist
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
from torch import nn
import matplotlib.pyplot as plt
train_batch_size = 64
test_batch_size = 128
learning_rate = 0.01
num_epoches = 20
lr = 0.01
momentum = 0.5
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5],[0.5])])
train_dataset = mnist.MNIST('./data',train=True,transform = transform,download=True)
test_dataset = mnist.MNIST('./data',train=False,transform=transform)
train_loader = DataLoader(train_dataset,batch_size=train_batch_size,shuffle=True)
test_loader = DataLoader(test_dataset,batch_size=test_batch_size,shuffle=False)
examples = enumerate(test_loader)
# enumerate在字典上是枚举、列举的意思
batch_idx,(example_data,example_targets) = next(examples)
fig = plt.figure()
# 它创建一个窗口,各种属性都是默认设置,它创建的窗口立即成为当前窗口,
# 并显示在其他窗口之上,直到新的窗口被创建或者其他窗口被唤醒。
for i in range(6):
plt.subplot(2,3,i+1)
# subplot是python中子图的绘制 这里表示绘制2行3列的图 i+1表示位于子图中的哪个位置
plt.tight_layout()
# tight_layout()会自动调整子图参数 使之填充整个图像区域
plt.imshow(example_data[i][0],cmap='gray',interpolation='none')
# 热力图是一种数据的图形化表示,具体而言,就是将二维数组中的元素用颜色表示。
# 热力图之所以非常有用,是因为它能够从整体视角上展示数据,
# 更确切的说是数值型数据。
plt.title("Ground Truth:{}".format(example_targets[i]))
plt.xticks([])
plt.yticks([])
# xticks yticks 到底有什么用,其实就是想把坐标轴变成自己想要的样子
class Net(nn.Module):
# 构建网络
"""
sequential构建网络 Sequential()函数的功能是将网络的层组合在一起
"""
def __init__(self,in_dim,n_hidden_1,n_hidden_2,out_dim):
super(Net,self).__init__()
self.layer1 = nn.Sequential(nn.Linear(in_dim,n_hidden_1),nn.BatchNorm1d(n_hidden_1))
self.layer2 = nn.Sequential(nn.Linear(n_hidden_1,n_hidden_2),nn.BatchNorm1d(n_hidden_2))
self.layer3 = nn.Sequential(nn.Linear(n_hidden_2,out_dim))
def forward(self,x):
x = F.relu(self.layer1(x))
x = F.relu(self.layer2(x))
x = self.layer3(x)
return x
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = Net(28*28,300,100,10)
model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr = lr ,momentum=momentum)
losses = []
acces = []
eval_losses = []
eval_acces = []
for epoch in range(num_epoches):
train_loss = 0
train_acc = 0
model.train()
if epoch%5==0:
optimizer.param_groups[0]['lr']*=0.1
for img,label in train_loader:
img = img.to(device)
label = label.to(device)
img = img.view(img.size(0),-1)
out = model(img)
loss = criterion(out,label)
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_loss += loss.item()
_,pred = out.max(1)
num_correct = (pred == label).sum().item()
acc = num_correct / img.shape[0]
train_acc += acc
losses.append(train_loss/len(train_loader))
acces.append(train_acc/len(train_loader))
eval_loss = 0
eval_acc = 0
model.eval()
for img ,label in test_loader:
img = img.to(device)
label = label.to(device)
img = img.view(img.size(0),-1)
out = model(img)
loss = criterion(out,label)
eval_loss += loss.item()
_,pred = out.max(1)
num_correct = (pred == label).sum().item()
acc = num_correct/img.shape[0]
eval_acc += acc
eval_acces.append(eval_acc/len(test_loader))
eval_losses.append(eval_loss/len(test_loader))
print('epoch:{},Train Loss:{:.4f},Train Acc:{:.4f},Test Loss:{:.4f},Test Acc: {:.4f}'.format(epoch,train_loss/len(train_loader),train_acc/len(train_loader),eval_loss/len(test_loader),eval_acc/len(test_loader)))