思路:首先建立一个数据集,该数据集是由两种不同类型的数据拼接而成的。然后建立神经网络,通过训练神经网络来使其分类误差减小,最后可视化结果。
建立数据集
import torch
import matplotlib.pyplot as plt
n_data = torch.ones(100,2)
x0 = torch.normal(2*n_data, 1)
y0 = torch.zeros(100)
x1 = torch.normal(-2*n_data, 1)
y1 = torch.zeros(100)
x = torch.cat((x0, x1), 0).type(torch.FloatTensor) #拼接
y = torch.cat((y0, y1), ).type(torch.LongTensor)
plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=y.data.numpy(), s=100, lw=0, cmap='RdYlGn')
plt.show()
函数剖析:
torch.normal(means, std, out=None)
返回一个张量,包含从给定参数means,std的离散正态分布中抽取随机数。均值means是一个张量,包含每一个输出元素相关的正态分布的均值。std是一个张量,包含每个输出元素相关的正态分布的标准差。均值和标准差的形状不须匹配,但每个张量的元素个数须相同。
参数:
#means(Tensor) — 均值
#std(Tensor) — 标准差
#out(Tensor) — 可选的输出张量
torch.normal(means, std-1.0, out=None)
所有抽取的样本共享标准差
torch.cat(seq, dim=0, out=None) → Tensor
在给定维度上对输入的张量序列seq进行连接操作。
torch.cat()可以看做torch.split()和torch.chunk()的逆运算。
cat()函数可以通过下面例子很好的理解。
参数:
#seq(Tensor的序列) — 可以是相同类型的Tensor的任何python序列。
#dim(int, 可选) — 张量连接的尺寸
#out(Tensor,可选) — 输出参数
建立神经网络
import torch
import torch.nn.Functional as F
class Net(torch.nn.Module):
def __init__(self, n_feature, n_hidden, n_output):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(n_feature, n_hidden)
self.output = torch.nn.Linear(n_hidden, n_output)
def forward(x):
x = F.relu(self.hidden(x))
x = self.output(x)
return x
net = Net(2,10,2)
print(net)
训练网络
optimizer = torch.optim.SGD(net.parameters(), lr=0.02)
loss_func = torch.nn.CrossEntryLoss()
for t in range(100):
out = net(x)
loss = loss_func(out, y)
optimizer.zero_grad()
loss.backward()
optimzer.step()
可视化训练
import matplotlib.pyplot as plt
plt.ion()
plt.show()
for t in range(100):
...
if t%2 == 0:
plt.cla()
prediction = torch.max(F.softmax(out), 1)[1] #返回索引
pred_y = prediction.data.numpy().squeeze() #目的是让其与target_y形状一致
target_y = y.data.numpy()
plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=pred_y, s=100, lw=0, cmap=''RdYlGn')
accuracy = sum(pred_y == target_y)/200
plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy, fontdict={'size':20, 'color':'red'})
plt.pause(0.1)
plt.ioff() #停止画图
plt.show()
torch.max()
返回输入张量所有元素的最大值
参数:
#input(Tensor) — 输入张量
torch.max(input, dim, max=None, max_indices=None) -> (Tensor, LongTensor)
返回输入张量给定维度上每行的最大值, 并同时返回每个最大值的位置索引。
输出形状中, 将dim维设定为1,其它与输入形状保持一致。
参数:
#input(Tensor) — 输入张量
#dim(int) — 指定的维度
#max(Tensor, 可选的) — 结果张量,包含给定维度上的最大值
#max_indices(LongTensor, 可选的) — 结果张量,包含给定维度上每个最大值的位置索引
例子:
>> a = torch.randn(4, 4)
>> a
0.0692 0.3142 1.2513 -0.5428
0.9288 0.8552 -0.2073 0.6409
1.0695 -0.0101 -2.4507 -1.2230
0.7426 -0.7666 0.4862 -0.6628
torch.FloatTensor of size 4x4]
>>> torch.max(a, 1)
(
1.2513
0.9288
1.0695
0.7426
[torch.FloatTensor of size 4x1]
,
2
0
0
0
[torch.LongTensor of size 4x1]
)
torch.max(input, other, out=None) → Tensor
返回输入张量给定维度上每行的最大值,并同时返回每个最大值的位置索引。 即,( out_i=max(input_i,other_i) )
输出形状中,将dim维设定为1,其它与输入形状保持一致。
参数:
#input (Tensor) – 输入张量
#other (Tensor) – 输出张量
#out (Tensor, 可选的) – 结果张量
完整代码
import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt
n_data = torch.ones(100, 2)
#返回由标量值 1 填充的张量,其形状由可变参数大小定义,数据大小为100,输出2
x0 = torch.normal(-2*n_data, 1)
#mean:均值,std:标准差,out:可选的输出张量
#选择均值为2*n_data,标准差为1的赋值到x0
y0 = torch.ones(100)
'''
输入:
import torch
x=torch.zeros(3)
print(x)
结果:
tensor([0., 0., 0.])
'''
x1 = torch.normal(2*n_data, 1)
y1 = torch.zeros(100)
x = torch.cat((x0, x1), 0).type(torch.FloatTensor)
y = torch.cat((y0, y1), ).type((torch.LongTensor))
#值拼接,都分别放到定义的x和y中去
print(x)
print(y)
class Net(torch.nn.Module):
def __init__(self, n_feature, n_hidden, n_output):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(n_feature, n_hidden)
self.out = torch.nn.Linear(n_hidden, n_output)
def forward(self, x):
x = F.relu(self.hidden(x))
x = self.out(x)
return x
net = Net(n_feature=2, n_hidden = 10, n_output=2)
print(net)
optimizer = torch.optim.SGD(net.parameters(), lr=0.02)
loss_func = torch.nn.CrossEntropyLoss()
#交叉熵损失函数
plt.ion()
for t in range(100):
out = net(x)
loss = loss_func(out, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if t % 2 == 0:
plt.cla()
prediction = torch.max(F.softmax(out), 1)[1]
pred_y = prediction.data.numpy()
target_y = y.data.numpy()
plt.scatter(x.data.numpy()[:,0],x.data.numpy()[:,1],c=pred_y,s=100,lw=0,cmap='RdYlGn')
accuracy = float((pred_y == target_y).astype(int).sum()) / float(target_y.size)
plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy, fontdict={'size': 20, 'color': 'blue'})
plt.pause(0.1)
plt.ioff()
plt.show()