Open NarcissusInMirror opened 4 years ago
每个tensor可以记录梯度;这个自定义的过程比nn.Module要多定义一个backward函数,也就是需要自定义梯度怎么回传;backward最后返回的是一个和输入形状一样的tensor,每个位置对应着
输入数据维度:(sample_size, 25)
标签:(sample_size)
可以看到,要求的输入维度形状,即
output = model.forward(input_data)
中output
的形状为(批大小,分类个数 )
,维度为2;输入的标签维度应为(批大小,)
,维度为1,且以0~N-1
代表N
个类别,不接受二维的one-hot编码,这些需要在进行数据处理时注意。
1d的batchnorm输入的向量是2维或者3维的,即(批大小,特征维数)
或(批大小,通道数,特征维数)
。当输入为2维时features参数为特征维数;当输入为3维时,features参数为通道数。但实际上都是沿着channel的维度进行的batchnorm。
顺带学习一下2d的batchnorm。batchnorm2d的输入必须是4维的,(批大小,通道数,图像高度,图像宽度)
,num_features为通道数。
以np.mean(nparray, axis)为例
>>> a = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9], [10, 11, 12])
>>> a
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
>>> a.shape
(4, 3)
>>> np.mean(a, axis=0)
array([5.5, 6.5, 7.5])
>>> np.mean(a, axis=1)
array([ 2., 5., 8., 11.])
以axis=0为例,a.shape=[4, 3]
四行三列,当选择axis=0
时,即选中4
,求平均时则求的是4个元素的平均,即按列平均。同理,axis=1时,选中3
,求平均时则求的是三个元素的平均,即按行平均。
torch.max(input, dim, keepdim=False, out=None) -> (Tensor, LongTensor)
>>> a = torch.randn(3,3)
>>> a
-0.7845 -1.7758 -1.5602
1.9941 -1.2037 -0.2332
0.1480 -0.0921 0.4939
[torch.FloatTensor of size 3x3]
>>> torch.max(a)
1.9940658807754517
>>> torch.max(a,0)
(
1.9941
-0.0921
0.4939
[torch.FloatTensor of size 3]
,
1
2
2
[torch.LongTensor of size 3]
)
先占个坑,本次实验中,需要把forward后的向量转成numpy数组进行一些操作,而输入的tensor经过了如下操作,大概是改为gpu向量,具体还需了解,回头补上。
data, label = data.cuda(), label.cuda()
data, label = Variable(data), Variable(label)
optimizer.zero_grad()
output = model.forward(data)
因此进行操作前需要先detach出来并且放到cpu中output = output.detach().cpu()
from scipy.special import softmax
output = softmax(output, axis=1)
存储:
torch.save(model, PATH),model为定义过的nn.Module的子类模块
加载:
model = torch.load(PATH)
model.eval()
# 保存和加载整个模型
torch.save(model_object, 'model.pkl')
model = torch.load('model.pkl')
# 仅保存和加载模型参数(推荐使用)
torch.save(model_object.state_dict(), 'params.pkl')
model_object.load_state_dict(torch.load('params.pkl'))
layers = []
layers.append(...) # 在layers中添加相应的层
return nn.Sequential(*layers) # 把layers中的层添加到sequential中
self.lateral_conv_1 = nn.Conv2d(64, 512, 1, bias=False) # 定义层
# 使用nn.init提供的初始化方法,参数传入相关层的需要初始化的参数
nn.init.kaiming_normal_(self.lateral_conv_1.weight, mode='fan_out', nonlinearity='relu')
# 对于Sequential来说,可以通过index来访问其中包含的层
self.fc1_1 = nn.Sequential(
nn.Linear(512 * 1 * 1, self.L),
nn.ReLU(),
)
nn.init.normal_(self.fc1_1[0].weight)
torch.nn.Parameter
Parameter类是
Tensor
的子类,是一个模型内可以进行梯度更新的参数,可通过model.parameters()
进行迭代,在优化器中会指定这些参数
因此,如果只是定义了
tensor
,没有加到模型的parameter
里面,这些tensor
是无法被训练的,即使requires_grad
设置为了True
,因此需要用Parameter
对tensor
进行包装。以下的代码写在模块的__init__
函数下,会自动认为加入到当前模块中下面的代码是在模块中加入
parameter
的另一种方法,name
参数传入字符串,可以通过这个名字来访问该parameter
,param
参数则是需要加入模块的parmameter
,注意,必须是parameter
,tensor
不行,这里可能是用来加入到其他模块中?