文章目录
- tensor
-
- 声明
- 操作
- 与Numpy交互
- 建立GPU的device
- 自微分(求导)
-
- 张量激活
- 梯度激活
- 神经网络搭建(torch.nn)
- 损失函数及优化策略
- 训练
tensor
声明
import torch
x = torch.empty(5, 3)
print("初始化一个(5,3)的tensor:{}".format(x))
x1 = torch.rand(5, 3)
print(
"生成一个均匀分布的初始化的,每个元素从0~1的张量,与第一个要区别开,另外,还有其它的随机张量生成函数,如torch.randn()、torch.normal()、torch.linespace(),分别是标准正态分布,离散正态分布,线性间距向量{}".format(
x1))
x2 = torch.zeros(5, 3, dtype=torch.long)
print("初始化一个全零张量,可以指定每个元素的类型{}".format(x2))
y = torch.tensor([5.3, 3])
print("已有矩阵转化为张量{}".format(y))
y1 = x1.new_ones(5, 3, dtype=torch.double)
print("从已有张量中创造一个张量,新的张量将会重用已有张量的属性。如:若不提供新的值,那么每个值的类型将会被重用。{}".format(y1))
y2 = torch.randn_like(x1, dtype=torch.float)
print("从已有张量中创造一个随机张量{}".format(y2))
print(x.shape)
操作
import torch
x = torch.rand(5, 3)
y = torch.rand(5, 3)
print("代数求和{}".format((x + y).shape))
add_value = torch.rand(5, 3)
print("添加参数的代数求和{}".format(torch.add(x, y, out=add_value)))
print("代数求和{}".format(y.add_(x)))
print("改变x的形状:改变前{0}——改变后{1}".format(x.shape, x.view(15).shape))
与Numpy交互
import numpy as np
import torch
a = torch.rand(5, 3)
b = np.zeros((5, 3))
print("转换前:{0},转换后:{1}".format(type(a), type(a.numpy())))
print("转换前:{0},转换后:{1}".format(type(b), type(torch.from_numpy(b))))
建立GPU的device
if torch.cuda.is_available():
device = torch.device("cuda")
自微分(求导)
张量激活
import torch
x = torch.ones(2, 2, requires_grad=True)
print(x)
y = x + 2
print(y)
print(y.grad_fn)
z = y * y * 3
out = z.mean()
print(z, out)
a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)
梯度激活
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)
print(x.requires_grad)
print((x ** 2).requires_grad)
with torch.no_grad():
print((x ** 2).requires_grad)
神经网络搭建(torch.nn)
from torch import nn
import torch
class encoding_block(nn.Module):
"""
Convolutional batch norm block with relu activation (main block used in the encoding steps)
"""
def __init__(
self,
in_size,
out_size,
kernel_size=3,
padding=0,
stride=1,
dilation=1,
batch_norm=True,
dropout=False,
):
super().__init__()
if batch_norm:
layers = [
nn.ReflectionPad2d(padding=(kernel_size - 1) // 2),
nn.Conv2d(
in_size,
out_size,
kernel_size=kernel_size,
padding=padding,
stride=stride,
dilation=dilation,
),
nn.PReLU(),
nn.BatchNorm2d(out_size),
nn.ReflectionPad2d(padding=(kernel_size - 1) // 2),
nn.Conv2d(
out_size,
out_size,
kernel_size=kernel_size,
padding=padding,
stride=stride,
dilation=dilation,
),
nn.PReLU(),
nn.BatchNorm2d(out_size),
]
else:
layers = [
nn.ReflectionPad2d(padding=(kernel_size - 1) // 2),
nn.Conv2d(
in_size,
out_size,
kernel_size=kernel_size,
padding=padding,
stride=stride,
dilation=dilation,
),
nn.PReLU(),
nn.ReflectionPad2d(padding=(kernel_size - 1) // 2),
nn.Conv2d(
out_size,
out_size,
kernel_size=kernel_size,
padding=padding,
stride=stride,
dilation=dilation,
),
nn.PReLU(),
]
if dropout:
layers.append(nn.Dropout())
self.encoding_block = nn.Sequential(*layers)
def forward(self, input):
output = self.encoding_block(input)
return output
class decoding_block(nn.Module):
def __init__(self, in_size, out_size, batch_norm=False, upsampling=True):
super().__init__()
if upsampling:
self.up = nn.Sequential(
nn.Upsample(mode="bilinear", scale_factor=2),
nn.Conv2d(in_size, out_size, kernel_size=1),
)
else:
self.up = nn.ConvTranspose2d(in_size, out_size, kernel_size=2, stride=2)
self.conv = encoding_block(in_size, out_size, batch_norm=batch_norm)
def forward(self, input1, input2):
output2 = self.up(input2)
output1 = nn.functional.upsample(input1, output2.size()[2:], mode="bilinear")
return self.conv(torch.cat([output1, output2], 1))
class UNet(nn.Module):
"""
Main UNet architecture
"""
def __init__(self, num_classes=1):
super().__init__()
self.conv1 = encoding_block(3, 64)
self.maxpool1 = nn.MaxPool2d(kernel_size=2)
self.conv2 = encoding_block(64, 128)
self.maxpool2 = nn.MaxPool2d(kernel_size=2)
self.conv3 = encoding_block(128, 256)
self.maxpool3 = nn.MaxPool2d(kernel_size=2)
self.conv4 = encoding_block(256, 512)
self.maxpool4 = nn.MaxPool2d(kernel_size=2)
self.center = encoding_block(512, 1024)
self.decode4 = decoding_block(1024, 512)
self.decode3 = decoding_block(512, 256)
self.decode2 = decoding_block(256, 128)
self.decode1 = decoding_block(128, 64)
self.final = nn.Conv2d(64, num_classes, kernel_size=1)
def forward(self, input):
conv1 = self.conv1(input)
maxpool1 = self.maxpool1(conv1)
conv2 = self.conv2(maxpool1)
maxpool2 = self.maxpool2(conv2)
conv3 = self.conv3(maxpool2)
maxpool3 = self.maxpool3(conv3)
conv4 = self.conv4(maxpool3)
maxpool4 = self.maxpool4(conv4)
center = self.center(maxpool4)
decode4 = self.decode4(conv4, center)
decode3 = self.decode3(conv3, decode4)
decode2 = self.decode2(conv2, decode3)
decode1 = self.decode1(conv1, decode2)
final = nn.functional.upsample(
self.final(decode1), input.size()[2:], mode="bilinear"
)
return final
class UNetSmall(nn.Module):
"""
Main UNet architecture
"""
def __init__(self, num_classes=1):
super().__init__()
self.conv1 = encoding_block(3, 32)
self.maxpool1 = nn.MaxPool2d(kernel_size=2)
self.conv2 = encoding_block(32, 64)
self.maxpool2 = nn.MaxPool2d(kernel_size=2)
self.conv3 = encoding_block(64, 128)
self.maxpool3 = nn.MaxPool2d(kernel_size=2)
self.conv4 = encoding_block(128, 256)
self.maxpool4 = nn.MaxPool2d(kernel_size=2)
self.center = encoding_block(256, 512)
self.decode4 = decoding_block(512, 256)
self.decode3 = decoding_block(256, 128)
self.decode2 = decoding_block(128, 64)
self.decode1 = decoding_block(64, 32)
self.final = nn.Conv2d(32, num_classes, kernel_size=1)
def forward(self, input):
conv1 = self.conv1(input)
maxpool1 = self.maxpool1(conv1)
conv2 = self.conv2(maxpool1)
maxpool2 = self.maxpool2(conv2)
conv3 = self.conv3(maxpool2)
maxpool3 = self.maxpool3(conv3)
conv4 = self.conv4(maxpool3)
maxpool4 = self.maxpool4(conv4)
center = self.center(maxpool4)
decode4 = self.decode4(conv4, center)
decode3 = self.decode3(conv3, decode4)
decode2 = self.decode2(conv2, decode3)
decode1 = self.decode1(conv1, decode2)
final = nn.functional.upsample(
self.final(decode1), input.size()[2:], mode="bilinear"
)
return final
损失函数及优化策略
import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=0.01)
optimizer.zero_grad()
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()
训练
import torch
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
shuffle=True, num_workers=2)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,
download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
shuffle=False, num_workers=2)
classes = ('plane', 'car', 'bird', 'cat',
'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
import matplotlib.pyplot as plt
import numpy as np
def imshow(img):
img = img / 2 + 0.5
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()
dataiter = iter(trainloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
net = Net()
for epoch in range(2):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 2000 == 1999:
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')
dataiter = iter(testloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))
outputs = net(images)
_, predicted = torch.max(outputs, 1)
print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]
for j in range(4)))
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (
100 * correct / total))
class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs, 1)
c = (predicted == labels).squeeze()
for i in range(4):
label = labels[i]
class_correct[label] += c[i].item()
class_total[label] += 1
for i in range(10):
print('Accuracy of %5s : %2d %%' % (
classes[i], 100 * class_correct[i] / class_total[i]))