z=x.detach()
print(z.requires_grad)
print(x.requires_grad)
print(x.detach().requires_grad)
False
True
False
x = torch.ones(2,requires_grad=True)
print(x)
z = x + 2
print(z)
z.backward()
print(x.grad)
# 出现grad can be implicitly created only for scalar outputs
# 因为此时的y并不是一个标量(即它包含一个元素的数据)
# 意思是只有对标量输出它才会计算梯度,而求一个矩阵对另一矩阵的导数束手无策。
RuntimeError: grad can be implicitly created only for scalar outputs
x = torch.ones(2,requires_grad=True)
z = x + 2
z.sum().backward()#或者z.backward(torch.ones_like(x))
print(x.grad)
>>> tensor([1., 1.])
如果不是对应矩阵的单位向量也是可以的,但是计算导数会发生变化:
x = torch.tensor([2., 1.], requires_grad=True)
y = torch.tensor([[1., 2.], [3., 4.]], requires_grad=True)
z = torch.mm(x.view(1, 2), y)
print(f"z:{z}")
z.backward(torch.Tensor([[1., 0]]), retain_graph=True)
print(f"x.grad: {x.grad}")
print(f"y.grad: {y.grad}")
>>> z:tensor([[5., 8.]], grad_fn=<MmBackward>)
x.grad: tensor([[1., 3.]])
y.grad: tensor([[2., 0.],
[1., 0.]])
net=nn.Sequential(nn.Flatten(),
nn.Linear(784,256),
nn.ReLU(),
nn.Linear(256,10))
def init_weights(m):
if type(m)==nn.Linear:
nn.init.normal_(m.weight,std=0.01)
net.apply(init_weights)
a=np.arange(3).reshape(-1,1)
b=np.arange(10).reshape(1,-1)
print(a)
print(b)
np.power(a,b)
[[0]
[1]
[2]]
[[0 1 2 3 4 5 6 7 8 9]]
array([[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]], dtype=int32)
a=np.array([1,2,3,4,5])
b=np.arange(10).reshape(2,5)
print(a)
print(b)
print(np.dot(b,a))#多维(>2)数组与0维数组(标量)做dot操作,相当于每一行对应元素相乘再求和,但是注意这里的顺序不能错了,dot(b,a)
[1 2 3 4 5]
[[0 1 2 3 4]
[5 6 7 8 9]]
[ 40 115]
c=np.arange(5).reshape(5,1)
print(c)
print(np.dot(b,c))#多维(>2)数组与二维数组(注意这里不是标量),进行dot相当于矩阵乘法
[[0]
[1]
[2]
[3]
[4]]
[[30]
[80]]
d=np.arange(10).reshape(5,2)
print(d)
print(np.dot(d,b))#多维矩阵的dot相当于矩阵乘法
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
[[ 5 6 7 8 9]
[ 15 20 25 30 35]
[ 25 34 43 52 61]
[ 35 48 61 74 87]
[ 45 62 79 96 113]]
e=[1,2,3,4,5]
f=[1,2,3,4,5]
np.dot(e,f)#标量(可以是列表)的dot操作是直接点乘求和
55
tensor1 = torch.Tensor([1,2,3])
tensor2 =torch.Tensor([4,5,6])
ans = torch.matmul(tensor1, tensor2)
print('tensor1 : ', tensor1)
print('tensor2 : ', tensor2)
print('ans :', ans)
print('ans.size :', ans.size())
tensor1 : tensor([1., 2., 3.])
tensor2 : tensor([4., 5., 6.])
ans : tensor(32.)
ans.size : torch.Size([])
(2)二维*二维:就是矩阵乘法运算
(3)二维*一维:结果是矩阵向量积
tensor1 =torch.Tensor([[4,5,6],[7,8,9]])
tensor2 = torch.Tensor([1,2,3])
ans = torch.matmul(tensor1, tensor2)
print('tensor1 : ', tensor1)
print('tensor2 : ', tensor2)
print('ans :', ans)
print('ans.size :', ans.size())
tensor1 : tensor([[4., 5., 6.],
[7., 8., 9.]])
tensor2 : tensor([1., 2., 3.])
ans : tensor([32., 50.])
ans.size : torch.Size([2])
简单理解就是每一行都乘以那个1维的向量然后求和,最后组成一个一维的向量。
(4)一维*二维:开始变成 1 * m(一维的维度),也就是一个二维, 再进行正常的矩阵运算, 然后再去掉开始增加的一个维度
tensor1 = torch.Tensor([1,2,3]) # 注意这里是一维
tensor2 =torch.Tensor([[4,5],[4,5],[4,5]])
ans = torch.matmul(tensor1, tensor2)
print('tensor1 : ', tensor1)
print('tensor2 : ', tensor2)
print('ans :', ans)
print('ans.size :', ans.size())
tensor1 : tensor([1., 2., 3.])
tensor2 : tensor([[4., 5.],
[4., 5.],
[4., 5.]])
ans : tensor([24., 30.])
ans.size : torch.Size([2])
a = torch.ones((2,3)) #建立tensor
a2 = torch.norm(a) #默认求2范数
a1 = torch.norm(a,p=1) #指定求1范数
print(a)
print(a2)
print(a1)
tensor([[1., 1., 1.],
[1., 1., 1.]])
tensor(2.4495)
tensor(6.)
trainer=torch.optim.SGD([
{"params":net[0].weight,'weight_decay':2},
{"params":net[0].bias}],lr=lr)
trainer=torch.optim.SGD(net[0].parameters,lr=lr,weight_decay=2)
两种都是可以的,因为SGD的参数params是可迭代的:
也就是说传入的参数只要是列表并且列表中要是dict类型的,这样定义好哪个参数是哪个或者net.parameters()出来的generator都可以的,都可以使用for循环来进行迭代。
a = np.array([[1., 2.], [3., 4.]])
b = np.array([[1., 2.], [3., 4.]])
# 对应位置元素做乘法
c_1 = a * b
[[ 1. 4.]
[ 9. 16.]]
# 线性代数中常规的矩阵乘法
c_2 = np.dot(a, b) # 等价于 a @ b
[[ 7. 10.]
[15. 22.]]
# 对应位置元素做乘法
c_3 = np.multiply(a, b)
[[ 1. 4.]
[ 9. 16.]]
a = np.mat([[1., 2.], [3., 4.]])
b = np.mat([[1., 2.], [3., 4.]])
# 线性代数中常规的矩阵乘法
c_1 = a * b
[[ 7. 10.]
[15. 22.]]
# 线性代数中常规的矩阵乘法
c_2 = np.dot(a, b)
[[ 7. 10.]
[15. 22.]]
# 对应位置元素做乘法
c_3 = np.multiply(a, b)
[[ 1. 4.]
[ 9. 16.]]
pytorch:
(1) torch.mul(a, b)(与*相等)
可以广播, 是矩阵a和b 对应位相乘,a和b的维度必须相等,比如a的维度是(1, 2),b的维度是(1, 2),返回的仍是(1, 2)的矩阵;或者a和b的行向量数目是一样的就可以广播了。
(2) torch.mm(a, b)
是矩阵a和b矩阵相乘,比如a的维度是(1, 2),b的维度是(2, 3),返回的就是(1, 3)的矩阵。只能处理二维矩阵
(3) torch.matmul() 能处理batch、广播的矩阵,等价于使用 @
当输入是一维和一维时,结果是对应元素相乘再求和
当输入是二维时,和 torch.mm 函数用法相同
当输入是多维时,把多出的一维(第一维)作为batch提出来,其他部分做矩阵乘法
当输入是向量(一维)和n维(n>2),将向量增加一个维度相当于列向量,然后与多维矩阵乘法,结果的维度是n-1
例子:
a = torch.tensor([[1., 2.], [3., 4.]])
b = torch.tensor([[1., 2.], [3., 4.]])
c_1 = torch.mm(a, b)
tensor([[ 7., 10.],
[15., 22.]])
c_2 = torch.mul(a, b)
tensor([[ 1., 4.],
[ 9., 16.]])
a = torch.ones((5, 3, 4))
b = torch.ones((4, 2))
c = torch.matmul(a, b)
print(c.shape)
torch.Size([5, 3, 2])
a = torch.ones((2, 3, 4))
b = torch.ones((1, 4, 2))
c = torch.matmul(a, b)
print(c.shape)
torch.Size([2, 3, 2])
a = torch.ones((2, 1, 3, 4))
b = torch.ones((1, 4, 2))
c = torch.matmul(a, b) # 等价于 c = a @ b
print(c.shape)
torch.Size([2, 1, 3, 2])
x = torch.tensor([1, 2, 3])
y = torch.tensor([[
[7, 8],
[9, 10],
[11,12]
]])
torch.matmul(x,y)
tensor([[58, 64]])
class Son(Father1, Father2):
def __init__(self):
super(Son, self).__init__()
mro列表=[Son, Father1, Father2, Base],super会从mro中,找到传入它的第一个参数’Son’,并第一个参数’Son’右边的一个类开始,依次寻找__init__函数。这里是从Father1开始寻找,一旦找到,就把找到的__init__函数绑定到self对象,并返回。如果想继承中调用Father2的__init__()方法,就应该写成:
class Son(Father1, Father2):
def __init__(self):
super(Father1, self).__init__()
# 元组-可以包含多个数据,因此可以使用元组让函数一次返回多个值
# 如果函数返回的类型是元组,小括号可以省略
# return (temp, wetness)
return temp, wetness # 小括号可以省略
train_ls, valid_ls = train(net, *data, num_epochs, learning_rate, weight_decay, batch_size) #这里的data就解包了
all_features=pd.concat((train_data.iloc[:,1:-1],test_data.iloc[:,1:]))#传参必须是列表或者元组这种iterable类型
print(type(all_features))
<class 'pandas.core.frame.DataFrame'>
numeric_features=all_features.dtypes[all_features.dtypes!='object'].index
all_features[numeric_features]=all_features[numeric_features].apply(lambda x:(x-x.mean())/(x.std()))
all_features[numeric_features]=all_features[numeric_features].fillna(0)#注意这两行左边写all_features[numeric_features]的话没办法改进去
def log_rmse(net, features, labels):
clipped_preds = torch.clamp(net(features),1,float('inf')) # 把模型输出的值限制在1和inf之间,inf代表无穷大(infinity的缩写)
rmse = torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels))) # 预测做log,label做log,然后丢到MSE损失函数里
return rmse.item()
test_data['SalePrice']=pd.Series(preds.reshape(1,-1)[0])#这里意思是先将preds变为一行的二维数组再取第一行元素出来,取得就是一维的了,才能变成Series类型
s=np.array([1,2,3,4,5]).reshape(1,-1)
print(s)
s=np.array([1,2,3,4,5]).reshape(1,-1)[0]
print(s)
[[1 2 3 4 5]]
[1 2 3 4 5]