1.导入所需的包
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.__version__
'3.4.1'
如果matplotlib版本较低的话(比如3.2.2),在执行的时候jupyter 内核会中断,我也不知道为什么,找了好久才找到是这个原因
2.用matplotlib读取本地图片
用python打开本地图片的方式有很多,此处用matplotlib
image = np.array(plt.imread('data/deeplearningail1w2/dog1.jpg'))
plt.imshow(image)
image.shape
(690, 461, 3)
所以我们要输入的图片的通道需要在最后一个维度
3.将随机生成的张量当成图片输出
以下是随机生成一张图片的例子
image = np.random.randint(0,255,(16,16,3))
plt.imshow(image)
随机生成的张量,所以生成的是一张马赛克似的图片,倒是情理之中
4.新建一个简单的卷积网络
net = nn.Sequential(
nn.Conv2d(3,16,3),
nn.Conv2d(16,32,3),
nn.Conv2d(32,16,3),
nn.Conv2d(16,3,3)
)
就随便叠了几个卷积层
5.将图片输入进网络
将我们的图片输入进去,但是只有一张图片,需要将它按以下要求处理一下:
- x是一个张量
- x的维度是这样的:
(sample_num, channels, height, width)
所以需要先将x转换成张量,并增加第0个维度,然后将通道维度换到第一个维度上
x = np.array(plt.imread('data/deeplearningail1w2/dog1.jpg'))
x.shape
(690, 461, 3)
x = torch.from_numpy(x) # 转换成张量
x = x.float() # 将它的数据类型转换成float32
x = x.permute(2,0,1) # 交换它的维度
x = x.unsqueeze(0) # 增加第0个维度
x.shape
torch.Size([1, 3, 690, 461])
上面是变换后的维度,然后输入到刚定义的网络里
y = net(x)
print(y.shape)
torch.Size([1, 3, 682, 453])
如果想要把y当做图片输出,需要将y的输出通道数移到最后面
y = y.permute([0,2,3,1])
变换成的shape如下
y.shape
torch.Size([1, 682, 453, 3])
因为经过网络过后的输出值是带有梯度的,所以只取它的data部分,
plt.imshow(np.array(y[0].data))
6.用随机生成的张量输入进网络
x = torch.randn(5,3,64,64) # samples, channels, height, width
y = net(x)
print(y.shape)
输出的维度如下
torch.Size([5, 3, 56, 56])
通道还是要提到最后面
y = y.permute([0,2,3,1])
y.shape
torch.Size([5, 56, 56, 3])
将输出的y输出成图片
plt.figure(dpi=100)
ax = plt.subplot(231)
for i,img in enumerate(y):
ax = plt.subplot(3, 3, i+1)
ax.imshow(img.data)
ax.set_xticks([])
ax.set_yticks([])
plt.show()