66pytorch函数详解 附带测试demo

本文详细介绍了PyTorch中常用函数的功能与用法,包括张量操作、绘图、损失函数、优化器等核心组件,适合初学者快速掌握PyTorch编程技巧。

“”"
-------------------torch 函数详解----------------------------
“”"

import numpy as np
import torch
from torch.autograd import Variable
from torch import nn
import matplotlib.pyplot as plt

“”“1.torch.is_tensor(x):如果obj 是一个pytorch张量,则返回True”""

x = torch.Tensor(2,3,4) #新建一个pytorch张量
torch.is_tensor(x)
print('result:', torch.is_tensor(x))

输出结果:
	result: True

“”“2.torch.is_storage(x):如何x 是一个pytorch storage对象,则返回True”""

print(torch.is_storage(x))
输出结果:
	False

“”“3.torch.numel:返回x 张量中的元素个数”""

print(torch.numel(x))
输出结果:
	24

“”“4.torch.eye(n, m=None, out=None):返回一个2维张量,对角线位置全1,其它位置全0"”"

y = torch.eye(3)
print(y)
输出结果:
tensor([[1., 0., 0.],
    [0., 1., 0.],
    [0., 0., 1.]])

“”“5.torch.from_numpy(ndarray):Numpy桥,将numpy.ndarray 转换为pytorch的 Tensor。
返回的张量tensor和numpy的ndarray共享同一内存空间。修改一个会导致另外一个也被修改。返回的张量不能改变大小”""

a = np.array([1,2,3])
t = torch.from_numpy(a)
print(t)
输出结果:
	tensor([1, 2, 3], dtype=torch.int32)

“”“6.torch.linspace:返回一个1维张量,包含在区间start 和 end 上均匀间隔的steps个点。 输出1维张量的长度为steps
start (float) – 序列的起始点
end (float) – 序列的最终值
steps (int) – 在start 和 end间生成的样本数
out (Tensor, optional) – 结果张量
“””

print(torch.linspace(3, 10, steps=5))
输出:
	tensor([ 3.0000,  4.7500,  6.5000,  8.2500, 10.0000])

“”“7.torch.logspace(start, end, steps=100, out=None):返回一个1维张量,包含在区间 10^start和 10^end上以对数刻度均匀间隔的steps个点。
输出1维张量的长度为steps
start (float) – 序列的起始点
end (float) – 序列的最终值
steps (int) – 在start 和 end间生成的样本数
out (Tensor, optional) – 结果张量
“””

print(torch.logspace(start=-10, end=10, steps=5))
输出:
	tensor([1.0000e-10, 1.0000e-05, 1.0000e+00, 1.0000e+05, 1.0000e+10])

“”“8.torch.ones(*sizes, out=None):返回一个全为1 的张量,形状由可变参数sizes定义。
sizes (int…) – 整数序列,定义了输出形状
out (Tensor, optional) – 结果张量 例子:
“””

print(torch.ones(2, 3))
输出结果:
	tensor([[1., 1., 1.],
	        [1., 1., 1.]])

“”“9.torch.rand(*sizes, out=None):返回一个张量,包含了从区间[0,1)的均匀分布中抽取的一组随机数,形状由可变参数sizes 定义。
sizes (int…) – 整数序列,定义了输出形状
out (Tensor, optinal) - 结果张量 例子:
“””

print(torch.rand(3))
输出结果:
	tensor([0.1480, 0.2517, 0.1265])

“”“10.torch.randn:返回一个张量,包含了从标准正态分布(均值为0,方差为 1,即高斯白噪声)中抽取一组随机数,形状由可变参数sizes定义”""

print("torch.randn: ", torch.randn(3))
输出结果:
	torch.randn:  tensor([1.2205, 0.2615, 0.4777])

“”“11.torch.randperm:给定参数n,返回一个从0 到 n - 1 的随机整数排列”""

print(torch.randperm(3))
输出结果:	
	tensor([2, 0, 1])

“”“12.torch.arange:返回一个1维张量,长度为 floor((end−start)/step)。包含从start到end,以step为步长的一组序列值(默认步长为1)。
参数:
start (float) – 序列的起始点
end (float) – 序列的终止点
step (float) – 相邻点的间隔大小
out (Tensor, optional) – 结果张量”""

print("torch.arange: ", torch.arange(1, 5, 1, out = x))
print("x: ", x)
输出结果:
	torch.arange:  tensor([1., 2., 3., 4.])
	x:  tensor([1., 2., 3., 4.])

“”"13.torch.range:返回一个1维张量,有 floor((end−start)/step)+1 个元素。包含在半开区间[start, end)
从start开始,以step为步长的一组值。 step 是两个值之间的间隔,即 xi+1=xi+stepxi+1=xi+step

警告:建议使用函数 torch.arange()

参数:
start (float) – 序列的起始点
end (float) – 序列的最终值
step (int) – 相邻点的间隔大小
out (Tensor, optional) – 结果张量"""

print("torch.range: ", torch.range(1.3, 5.6))
输出结果:
	torch.range:  tensor([1.3000, 2.3000, 3.3000, 4.3000, 5.3000])

“”"14.torch.zeros:返回一个全为标量 0 的张量,形状由可变参数sizes 定义。

参数:
sizes (int…) – 整数序列,定义了输出形状
out (Tensor, optional) – 结果张量"""

print("torch.zeros: ", torch.zeros(5))
输出结果:
	torch.zeros:  tensor([0., 0., 0., 0., 0.])

“”"15.torch.max:返回输入张量所有元素的最大值。
a.参数:input (Tensor) – 输入张量

b.参数:
input (Tensor) – 输入张量
dim (int) – 指定的维度
max (Tensor, optional) – 结果张量,包含给定维度上的最大值
max_indices (LongTensor, optional) – 结果张量,包含给定维度上每个最大值的位置索引

c.参数:
input (Tensor) – 输入张量
other (Tensor) – 输出张量
out (Tensor, optional) – 结果张量
“”"

aa = torch.randn(5)
print(aa)
print("torch.max111: ", torch.max(aa))
输出结果:
	tensor([ 0.4969, -0.1609, -1.3744, -0.6532,  1.2244])
	torch.max111:  tensor(1.2244)

“”“dim=1 :取矩阵的每一行最大的值 组成一个1维矩阵。dim的值必须小于aa1的维度,比如:如果aa1是2维矩阵那么dim得小于2, aaa1为3为矩阵 dim的值得小于3
dim > 1 :取矩阵的每一列最大的值 组成一个矩阵
“””

aa2 = torch.randn(3, 4)
print(aa2)
print("torch.max222: ", torch.max(aa2, dim=1))
输出结果:
	tensor([[ 1.4783,  1.5988,  0.6321, -0.8419],
    [-1.6461,  1.4878,  0.9888, -0.2271],
    [ 0.6326,  0.1875,  0.6437, -0.9330]])
    
	torch.max222:  torch.return_types.max(
	values=tensor([1.5988, 1.4878, 0.6437]),
	indices=tensor([1, 1, 2]))

aa1 = torch.randn(2, 5, 6)
print(aa1)
输出结果:
	tensor([[[ 0.4342,  2.1148, -0.5727, -0.1438, -1.2496,  0.5915],
     [-0.6340, -0.5718,  0.7919, -0.5353,  0.0998, -1.6941],
     [-0.4791, -0.3789,  1.8555,  1.3287,  0.5841, -0.4429],
     [-1.3211,  1.2741, -1.7600,  0.2985, -1.0295,  1.2520],
     [ 0.9671, -0.5196, -0.7857, -0.0560,  0.2304,  0.2697]],

    [[-1.0855, -0.6774,  0.5850,  0.2507, -0.4710,  1.1073],
     [-0.2189, -0.2839, -1.2439,  1.2105, -0.6102, -0.3298],
     [-0.4399, -0.3557, -0.7534,  0.4810, -1.2203,  0.7078],
     [-0.6699,  2.0302, -1.3209,  0.0196,  1.5503,  0.5045],
     [-0.7213, -0.0689, -0.4742,  2.1822, -1.0017,  1.5620]]])

ddww,dede = torch.max(aa1, dim=2)
print("torch.max333: ", ddww, "rfrfrf: ", dede)
输出结果:
	torch.max333:  tensor([[2.1148, 0.7919, 1.8555, 1.2741, 0.9671],
    [1.1073, 1.2105, 0.7078, 2.0302, 2.1822]]) rfrfrf:  tensor([[1, 2, 2, 1, 0],
    [5, 3, 5, 1, 3]])

#aa2和bbb2个一维矩阵没一个元素对比 输出大的元素 一维矩阵

aa2 = torch.randn(5)
bbb = torch.randn(5)
print("aa2: ", aa2)
print("bbb: ", bbb)
print("torch.max2: ", torch.max(aa2, bbb))
输出结果:
	aa2:  tensor([ 1.5293,  0.8364, -0.0355,  1.4288,  0.6854])
	bbb:  tensor([-0.7501,  0.0315,  0.0835, -1.1763,  0.0222])
	torch.max2:  tensor([1.5293, 0.8364, 0.0835, 1.4288, 0.6854])

“”"16. torch.squeeze:将输入张量形状中的1 去除并返回。 如果输入是形如(A×1×B×1×C×1×D),那么输出形状就为: (A×B×C×D)
当给定dim时,那么挤压操作只在给定维度上。例如,输入形状为: (A×1×B), squeeze(input, 0) 将会保持张量不变,
只有用 squeeze(input, 1),形状会变成 (A×B)。

注意: 返回张量与输入张量共享内存,所以改变其中一个的内容会改变另一个。

参数:
input (Tensor) – 输入张量
dim (int, optional) – 如果给定,则input只会在给定维度挤压
out (Tensor, optional) – 输出张量"""

x1 = torch.zeros(2, 1, 2, 1, 3)
print("squeeze: ", torch.squeeze(x1).size()) #去掉所有的1
print("squeeze1: ", torch.squeeze(x1, 1).size()) #去掉第一个1
输出结果:
	squeeze:  torch.Size([2, 2, 3])
	squeeze1:  torch.Size([2, 2, 1, 3])

“”"17.MSELoss(size_average=None, reduce=None, reduction=‘mean’):很多的 loss 函数都有 size_average 和 reduce 两个布尔类型的参数。因为一般损失函数都是直接计算 batch 的数据,因此返回的 loss 结果都是维度为 (batch_size, ) 的向量。

(1)如果 reduce = False,那么 size_average 参数失效,直接返回向量形式的 loss
(2)如果 reduce = True,那么 loss 返回的是标量:
a)如果 size_average = True,返回 loss.mean();
b)如果 size_average = False,返回 loss.sum();

注意:默认情况下, reduce = True,size_average = True
“”"

a=np.array([[1,2],[3,6]])
b=np.array([[2,3],[8,5]])

#返回向量
loss_fn = nn.MSELoss(size_average=False, reduce=False)#一般要求用nn.MSELoss(reduction='none')
input = Variable(torch.from_numpy(a))
target = Variable(torch.from_numpy(b))
loss = loss_fn(input.float(), target.float())
print("loss: ", loss)
输出结果:
	loss:  tensor([[ 1.,  1.],
    [25.,  1.]])
    结果怎么算的?(2-1)的平方,(3-2)的平方,(8-3)的平方,(5-6)的平方即对应位置的差的平方值。

print("---------------------------------------")
#返回平局值
loss_fn1 = nn.MSELoss(size_average=True, reduce=True)#一般要求nn.MSELoss(reduction='mean')这样写
input = Variable(torch.from_numpy(a))
target = Variable(torch.from_numpy(b))
loss = loss_fn1(input.float(), target.float())
print("loss: ", loss)
输出结果为:
	loss:  tensor(7.) 怎么来的?上面算的(1+1+25+1)/4得到的

“”“18. item(): 一个tensor如果想要转换为标准的python对象数值,需要调用tensor.item(),这个方法只对包含一个元素的tensor适用.
实际就是讲张量转为数字,如下:
如果超过1个元素 必报错。
“””

x_train = np.array([[3.3]])
z1 = torch.from_numpy(x_train)
print("21212: ", z1.item())
输出结果:21212:  3.3

“”"19. plot() :画图
plot函数的一般的调用形式:
#单条线:
plot([x], y, [fmt], data=None, **kwargs)
#多条线一起画
plot([x], y, [fmt], [x2], y2, [fmt2], …, **kwargs)
可选参数[fmt] 是一个字符串来定义图的基本属性如:颜色(color),点型(marker),线型(linestyle),

具体形式 fmt = ‘[color][marker][line]’

fmt接收的是每个属性的单个字母缩写,例如: plot(x, y, ‘bo-’) # 蓝色圆点实线
label :标记每条线或点的 一般是名字之类的
“”"
import matplotlib.pyplot as plt

x = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168],
                    [9.779], [6.182], [7.59], [2.167], [7.042],
                    [10.791], [5.313], [7.997], [3.1]], dtype=np.float32)

y = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573],
                    [3.366], [2.596], [2.53], [1.221], [2.827],
                    [3.465], [1.65], [2.904], [1.3]], dtype=np.float32)
plt.plot(x, y, 'ro', label='swswsw')
plt.legend()
plt.show()

“”“20.交叉熵损失函数: CrossEntropyLoss():公式 loss(x, class) = -x[class] + log(exp(x[0]) + …+ exp(x[j]))
“””
“”“单维度测试--------------------------------------------”""

import torch
import torch.nn as nn
import math
loss = nn.CrossEntropyLoss()
input = torch.randn(1, 5, requires_grad=True)
target = torch.empty(1, dtype=torch.long).random_(4)
output = loss(input, target)

print("输入为5类:")
print(input)
print("要计算loss的类别:")
print(target)
print("计算loss的结果:")
print(output)

first = 0
for i in range(1):
    first -= input[i][target[i]] #**************    -x[class]

second = 0
for i in range(1):
    for j in range(5):
        second += math.exp(input[i][j]) #************* exp(x[0]) + ...+ exp(x[j])

res = 0
res += first + math.log(second) #********* -x[class] + log(exp(x[0]) + ...+ exp(x[j]))
print("自己的计算结果:")
print(res)

输出结果:
	输入为5类:
	tensor([[-1.0431, -0.1981,  1.3219, -1.8172, -0.4636]], requires_grad=True)
	要计算loss的类别:
	tensor([0])
	计算loss的结果:
	tensor(2.7861, grad_fn=<NllLossBackward>)
	自己的计算结果:
	tensor(2.7861, grad_fn=<AddBackward0>)

“”"------------------------------------------------------"""
“”“多维度测试-------------------------------------------”""

import torch
import torch.nn as nn
import math
loss = nn.CrossEntropyLoss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.empty(3, dtype=torch.long).random_(5)
output = loss(input, target)

print("输入为3个5类:")
print(input)
print("要计算loss的类别:")
print(target)
print("计算loss的结果:")
print(output)

first = [0,0,0]
for i in range(3):
    first[i] -= input[i][target[i]]
second = [0,0,0]
for i in range(3):
    for j in range(5):
        second[i] += math.exp(input[i][j])
res = 0
for i in range(3):
    res += first[i] +math.log(second[i])
print("自己的计算结果:")
print(res/3)

输出结果:
输入为3个5类:
tensor([[ 0.9773, -0.8612, -0.7163,  0.6097,  0.0114],
        [-0.2555, -1.4427,  1.9644, -0.7308,  2.1826],
        [ 0.3451, -1.3543,  0.0665,  0.5910,  0.2061]], requires_grad=True)
要计算loss的类别:
tensor([1, 3, 2])
计算loss的结果:
tensor(2.6667, grad_fn=<NllLossBackward>)
自己的计算结果:
tensor(2.6667, grad_fn=<DivBackward0>)

3维测试:

import torch
import torch.nn as nn
import math
loss = nn.CrossEntropyLoss()#计算公式:loss(x, class) = -x[class] + log(exp(x[0]) + ...+ exp(x[j]))
input = torch.randn(3, 5, 2, requires_grad=True)  #input就是x
target = torch.empty(3, 2, dtype=torch.long).random_(5) #target就是class
output = loss(input, target)

print("输入为3个5类:")
print(input)
print("要计算loss的类别:")
print(target)
print("计算loss的结果:")
print(output)

first = [[0,0],[0,0],[0,0]]
for i in range(3):
    for j in range(2):
        first[i][j] -= input[i][target[i][j]][j] #**************    -x[class]

second = [[0,0],[0,0],[0,0]]
for i in range(3):
    for j in range(5):
        for k in range(2):
            second[i][k] += math.exp(input[i][j][k])#************* exp(x[0]) + ...+ exp(x[j])

res = 0
for i in range(3):
    for j in range(2):
        res += first[i][j] +math.log(second[i][j]) #********* -x[class] + log(exp(x[0]) + ...+ exp(x[j]))
print("自己的计算结果:")
print(res/6)

输出结果:
	输入为3个5类:
	tensor([[[-0.8542, -0.2139],
	         [ 1.7634,  0.8149],
	         [-0.4763, -0.5300],
	         [-1.3903, -0.4187],
	         [ 1.4105, -0.3344]],

	        [[-0.8880, -0.4785],
	         [-2.3293, -1.0082],
	         [ 1.3367,  0.6445],
	         [-0.6875,  0.9052],
	         [-0.4579, -0.1773]],
	
	        [[-0.8935,  1.4309],
	         [ 0.9779, -0.4425],
	         [-0.0809, -1.0523],
	         [-0.3746, -0.2991],
	         [ 0.4313, -1.3516]]], requires_grad=True)
	要计算loss的类别:
		tensor([[2, 4],
		        [3, 4],
		        [1, 2]])
   计算loss的结果:
		tensor(2.1585, grad_fn=<NllLoss2DBackward>)
	自己的计算结果:
		tensor(2.1585, grad_fn=<DivBackward0>)

“”“21.torch.random_(from=0, to=None, *, generator=None)
将tensor用从在[from, to-1]上的正态分布或离散正态分布取样值进行填充。如果没有明确说明,则填充值仅由本tensor的数据类型限定。
random_(x):从[0, x-1]区间取任意一个数填充。
random_(x, y):从[x, y-1]区间取任意一个数填充。
“””

ss = torch.empty(1).random_(6)
print("212121: ", ss)
ss1 = torch.empty(1).random_(6, 9)
print("212121222: ", ss1)

“”"22. SGD:随机梯度下降法
keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
随机梯度下降法,支持动量参数,支持学习衰减率,支持Nesterov动量
参数:
lr:大或等于0的浮点数,学习率
momentum:大或等于0的浮点数,动量参数
decay:大或等于0的浮点数,每次更新后的学习率衰减值
nesterov:布尔值,确定是否使用Nesterov动量

有3组数据:
x1 = [2, 3, 4, 5]
x2 = [5, 6, 7, 8]
y = [30, 40 ,50 ,60]

h(x) = ax1 + bx2
梯度算法就是要获取a和b的值 让h(x)的值更接近y的值,同时让随时函数l = loss(x, class)的值l 最小。这就是梯度算法的核心

最终公式是:Q := Q - ρ∑((Yi - H(xi))xi) Q从0到j每一个Q这么算

优点:
随机梯度下降在计算下降最快的方向时时随机选一个数据进行计算,而不是扫描全部训练数据集,这样就加快了迭代速度。

随机梯度下降并不是沿着J(θ)下降最快的方向收敛,而是震荡的方式趋向极小点。
“”"

# -*- coding: utf-8 -*-
import random

# 用y = Θ1*x1 + Θ2*x2来拟合下面的输入和输出
# input1  1   2   5   4
# input2  4   5   1   2
# output  19  26  19  20
input_x = [[1, 4], [2, 5], [5, 1], [4, 2]]  # 输入
y = [19, 26, 19, 20]  # 输出

theta = [1, 1]  # θ参数初始化
loss = 10  # loss先定义一个数,为了进入循环迭代
step_size = 0.01  # 步长
eps = 0.0001  # 精度要求
max_iters = 10000  # 最大迭代次数
error = 0  # 损失值
iter_count = 0  # 当前迭代次数

while (loss > eps and iter_count < max_iters):  # 迭代条件
    loss = 0
    i = random.randint(0, 3)  # 每次迭代在input_x中随机选取一组样本进行权重的更新
    pred_y = theta[0] * input_x[i][0] + theta[1] * input_x[i][1]  # 预测值
    theta[0] = theta[0] - step_size * (pred_y - y[i]) * input_x[i][0]
    theta[1] = theta[1] - step_size * (pred_y - y[i]) * input_x[i][1]
    for i in range(3):
        pred_y = theta[0] * input_x[i][0] + theta[1] * input_x[i][1]  # 预测值
        error = 0.5 * (pred_y - y[i]) ** 2
        loss = loss + error
    iter_count += 1
    print('iters_count', iter_count)
print('theta: ', theta)
print('final loss: ', loss)
print('iters: ', iter_count)

“”“23.torch.view():返回一个有相同数据但大小不同的tensor。 返回的tensor必须有与原tensor相同的数据和相同数目的元素,
但可以有不同的大小。一个tensor必须是连续的contiguous()才能被查看。
另外,参数不可为空。参数中的-1就代表这个位置由其他位置的数字来推断,只要在不致歧义的情况的下,view参数就可以推断出来,也就是人可以推断出形状的情况下
“””

x = torch.randn(4, 4)
print("x: ", x)
print("x.size(): ", x.size())
y = x.view(16)
print("yyy: ", y)
print("y.size(): ", y.size())

z = x.view(-1, 8)  # the size -1 is inferred from other dimensions
print("zzzz: ", z)
print("z.size(): ", z.size())

“”“24.train_loader = DataLoader()”""

from torchvision import datasets
from torch.utils.data import DataLoader
from torchvision import transforms

train_dataset = datasets.MNIST(
    root='F:/PycharmProjects/pytorch-beginner-master/02-Logistic Regression/data', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = datasets.MNIST(
    root='F:/PycharmProjects/pytorch-beginner-master/02-Logistic Regression/data', train=False, transform=transforms.ToTensor())
batch_size = 32
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
print("训练集总长度: ", len(train_dataset))
print("每个mini_batch的size为32,一共有: ", len(train_loader), "个")

# for i, data in enumerate(train_loader, 1):
#     img, label = data  #j将数据从train_loader读出来 一次读取的样本数是32个
#     img, label = Variable(img), Variable(label)
#     print("img.data.size(): ", img.data.size(), "img.data.size(): ", label.data.size())

“”"25.torch.sum(): 返回输入张量input 所有元素的和。

输出形状与输入相同,除了给定维度上为1"""

a = torch.randn(2, 5)
print("cdcdcd: ", a)
print("sum: ", a.sum())

b = torch.randn(2, 5)
num_correct = (a == b).sum()
print("num_correct: ", num_correct)

“”“26.torch.nn.Linear():线形图存, 对传入数据应用线性变换:y = weight* x+ bias,PyTorch的nn.Linear()是用于设置网络中的全连接层的,需要注意的是全连接层的输入与输出都是二维张量,一般形状为[batch_size, size],不同于卷积层要求输入输出是四维张量。
参数:
in_features指的是输入的二维张量的大小,即输入的[batch_size, size]中的size的值
out_features指的是输出的二维张量的大小,即输出的二维张量的形状为[batch_size,output_size],当然,它也代表了该全连接层的神经元个数。
从输入输出的张量的shape角度来理解,相当于一个输入为[batch_size, in_features]的张量变换成了[batch_size, out_features]的输出张量。
bias - 如果设置为False,则图层不会学习附加偏差。默认值:True”""

x = torch.randn(2, 3)#输入[batch_size=2, size=3]
m = torch.nn.Linear(3, 2)#这里的3就是size,2是要输出的output_size。所以输出是[batch_size,2]
output = m(x)
print('m.weight.shape:\n ', m.weight.shape)
print('m.bias.shape:\n', m.bias.shape)#m.bias由batch_size决定,batch_size的值来源于in_features
print('output.shape:\n', output.shape)
输出结果:
		 m.weight.shape:torch.Size([2, 3])
		 m.bias.shape: torch.Size([2])
		 output.shape:torch.Size([2, 2])

“”"27.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1,
padding=0, dilation=1, groups=1,
bias=True, padding_mode=‘zeros’):2d卷积。
参数:
Input Channels:这个很好理解,就是输入的四维张量[N, C, H, W]中的C了,即输入张量的channels数。也就是输入图像的通道数
(如灰度图像就是1通道,RGB图像忽略alpha通道后就是3通道)。

out_channels:也很好理解,即期望的四维输出张量的channels数,不再多说

Kernel_Size:filter(卷积核)的大小(F),一般我们会使用5x5、3x3这种左右两个数相同的卷积核,因此这种情况只需要写kernel_size = 5这样的就行了。
如果左右两个数不同,比如3x5的卷积核,那么写作kernel_size = (3, 5),注意需要写一个tuple,而不能写一个列表(list)

Stride:步长(S),Stride指每次移动卷积核的步长,显然这个值会大幅影响输出的Feature Map的shape。

Padding:边界补充§,Padding指为输入图像外围补充的圈数,注意如28乘28的图像,补充Padding=1就变成30乘30的了(而不是29乘29)。这个值一般直接在卷积时候定义,
不必手动为输入图像加Padding。

计算公式:
输入的大小:W1 H1 D1
输出大小:W2 = ((W1-F+2P)/S) + 1
H2 = ((H1-F+2P)/S) + 1
D2 = K
“”"

"""2维的卷积层,用于图片的卷积"""
# 输入图像的通道数=1(灰度图像),卷积核的种类数=3(K)
# 卷积核的shape是3乘3的,扫描步长为1,不加padding
layer = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=3, stride=1, padding=0)

"""要输入的原始图像"""
# 样本数=1,通道数=1,图像的shape是28乘28的 w=28,F=3 S=1,根据W2 = ((W1-F+2P)/S) + 1算得w2 = (28 - 3)/1  + 1 = 26
x = torch.rand(1, 1, 28, 28)#根据计算公式 输出为:26*26*3
"""使用上面定义的卷积层layer和输入x,完成一次卷积的前向运算"""
out = layer.forward(x)
# 得到的还是1张图片,因为用了3种kernel所以输出的通道数变成3了
# 因为没加padding,原来28乘28的图像在3乘3卷积下得到的边长是28-3+1=26
print("out.shape: ", out.shape)  # torch.Size([1, 3, 26, 26])

"""添加padding看看"""
# 这次使用padding为1.所以原始图像上下左右都加了一层0
layer = nn.Conv2d(1, 3, kernel_size=3, stride=1, padding=1)
print(layer.forward(x).shape)  # torch.Size([1, 3, 28, 28])

"""步长设置为2看看"""
# stride设置为2,也就是每次移动2格子(向上或者向右)
layer = nn.Conv2d(1, 3, kernel_size=3, stride=2, padding=1)
# 相当于每次跳1个像素地扫描,输出的Feature Map直接小了一半
print(layer.forward(x).shape)  # torch.Size([1, 3, 14, 14])

"""实际使用时,应该这样用!"""
out = layer(x)
print(out.shape)  # torch.Size([1, 3, 14, 14])

“”"28. torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
如果padding不是0,会在输入的每一边添加相应数目0 比如padding=1,则在每一边分别补0 ,其实最后的结果补出来是bias

参数:

kernel_size(int or tuple) - max pooling的窗口大小,可以为tuple,在nlp中tuple用更多,(n,1)
stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
padding(int or tuple, optional) - 输入的每一条边补充0的层数
dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作
“”"

aa = torch.randn(4, 4, 2)
print("aa: ", aa)
bb = nn.MaxPool2d(kernel_size=2, stride=2)
c = bb(aa)
print("c: ", c)
print("c.shape", c.shape)

“”"29. nn.LSTM(in_dim, hidden_dim, n_layer, batch_first=True):LSTM循环神经网络
参数:
input_size: 表示的是输入的矩阵特征数
hidden_size: 表示的是输出矩阵特征数
num_layers 表示堆叠几层的LSTM,默认是1
bias: True 或者 False,决定是否使用bias
batch_first: True 或者 False,因为nn.lstm()接受的数据输入是(序列长度,batch,输入维数),这和我们cnn输入的方式不太一致,所以使用batch_first,我们可以将输入变成(batch,序列长度,输入维数)
dropout: 表示除了最后一层之外都引入一个dropout
bidirectional: 表示双向LSTM,也就是序列从左往右算一次,从右往左又算一次,这样就可以两倍的输出

batch_first: 输入输出的第一维是否为 batch_size,默认值 False。因为 Torch 中,人们习惯使用Torch中带有的dataset,
dataloader向神经网络模型连续输入数据,这里面就有一个 batch_size 的参数,表示一次输入多少个数据。 在 LSTM 模型中,
输入数据必须是一批数据,为了区分LSTM中的批量数据和dataloader中的批量数据是否相同意义,LSTM 模型就通过这个参数的设定来区分。
如果是相同意义的,就设置为True,如果不同意义的,设置为False。 torch.LSTM 中 batch_size 维度默认是放在第二维度,故此参数设置
可以将 batch_size 放在第一维度。如:input 默认是(4,1,5),中间的 1 是 batch_size,指定batch_first=True后就是(1,4,5)。所以,
如果你的输入数据是二维数据的话,就应该将 batch_first 设置为True;

“”"

import torch
import torch.nn as nn
from torch.autograd import Variable

#构建网络模型---输入矩阵特征数input_size、输出矩阵特征数hidden_size、层数num_layers
inputs = torch.randn(5,3,10)#   ->(seq_len,batch_size,input_size)
"""inputs = torch.randn(5,3,10) :bitch_size=5, seq_len=3,input_size=10
我的理解:有5个句子,每个句子3个单词,每个单词用10个实数向量表示;而句子的长度是不一样的,所以seq_len可长可短,这也是LSTM可以解决长短序列
的特殊之处。只有seq_len这一参数是可变的。
"""
rnn = nn.LSTM(10,20,2)#      ->   (input_size,hidden_size,num_layers)
h0 = torch.randn(2,3,20)#     ->(num_layers* 1,batch_size,hidden_size)
c0 = torch.randn(2,3,20)#     ->(num_layers*1,batch_size,hidden_size)
num_directions=1#   因为是单向LSTM
'''
Outputs: output, (h_n, c_n)
'''
output,(hn,cn) = rnn(inputs,(h0,c0))
#print("out:", out)

“”“30. x.size(num):获取维数”""

dede = torch.Tensor(3, 4, 5)
print("dedede: ", torch.Tensor(3, 4, 5).size(0)) #值是3
print("dedede2: ", torch.Tensor(3, 4, 5).size(1))#值是4
print("dedede3: ", torch.Tensor(3, 4, 5).size(2))#值是5
#print("dedede4: ", torch.Tensor(3, 4, 5).size(3))#报错


frfr = torch.cuda.get_device_name(0)
print("dedede: ", frfr)

31.torch.nn.ReLU(inplace=False):tensor所有的元素中如果小于零的就改为零
1.如果inplace为false,不改变输入,只改变输出
2.如果inplace为true,改变输入
如下例子:

import torch

input = torch.randn(8)
print('input: ', input)

input1 = torch.nn.ReLU(inplace=False)(input)
print('input: ', input)
print('input1: ', input1)

input2 = torch.nn.ReLU(inplace=True)(input)
print('input: ', input)
print('input2: ', input2)
输出结果:
input:  tensor([-0.1985, -1.4657,  0.1393, -1.6685,  0.1855, -0.5001, -1.0144,  0.1143])
input:  tensor([-0.1985, -1.4657,  0.1393, -1.6685,  0.1855, -0.5001, -1.0144,  0.1143])
input1:  tensor([0.0000, 0.0000, 0.1393, 0.0000, 0.1855, 0.0000, 0.0000, 0.1143])
input:  tensor([0.0000, 0.0000, 0.1393, 0.0000, 0.1855, 0.0000, 0.0000, 0.1143])
input2:  tensor([0.0000, 0.0000, 0.1393, 0.0000, 0.1855, 0.0000, 0.0000, 0.1143])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值