1 Tensor
torch.Tensor
是一种包含单一数据类型元素的多维矩阵
Torch定义了10种CPU tensor类型和GPU tensor类型:
Data type | dtype | CPU tensor | GPU tensor |
---|---|---|---|
32-bit floating point | torch.float32 or torch.float |
torch.FloatTensor |
torch.cuda.FloatTensor |
64-bit floating point | torch.float64 or torch.double |
torch.DoubleTensor |
torch.cuda.DoubleTensor |
16-bit floating point [1] | torch.float16 or torch.half |
torch.HalfTensor |
torch.cuda.HalfTensor |
16-bit floating point [2] | torch.bfloat16 |
torch.BFloat16Tensor |
torch.cuda.BFloat16Tensor |
32-bit complex | torch.complex32 or torch.chalf |
||
64-bit complex | torch.complex64 or torch.cfloat |
||
128-bit complex | torch.complex128 or torch.cdouble |
||
8-bit integer (unsigned) | torch.uint8 |
torch.ByteTensor |
torch.cuda.ByteTensor |
8-bit integer (signed) | torch.int8 |
torch.CharTensor |
torch.cuda.CharTensor |
16-bit integer (signed) | torch.int16 or torch.short |
torch.ShortTensor |
torch.cuda.ShortTensor |
32-bit integer (signed) | torch.int32 or torch.int |
torch.IntTensor |
torch.cuda.IntTensor |
64-bit integer (signed) | torch.int64 or torch.long |
torch.LongTensor |
torch.cuda.LongTensor |
Boolean | torch.bool |
torch.BoolTensor |
torch.cuda.BoolTensor |
quantized 8-bit integer (unsigned) | torch.quint8 |
torch.ByteTensor |
/ |
quantized 8-bit integer (signed) | torch.qint8 |
torch.CharTensor |
/ |
quantized 32-bit integer (signed) | torch.qint32 |
torch.IntTensor |
/ |
quantized 4-bit integer (unsigned) [3] | torch.quint4x2 |
torch.ByteTensor |
/ |
创建
一个张量tensor可以从Python的list
或序列构建
torch.FloatTensor([[1, 2, 3], [4, 5, 6]])
Out[0]:
tensor([[1., 2., 3.],
[4., 5., 6.]])
根据可选择的大小和数据新建一个tensor。 如果没有提供参数,将会返回一个空的零维张量。如果提供了numpy.ndarray
,torch.Tensor
或torch.Storage
,将会返回一个有同样参数的tensor.如果提供了python序列,将会从序列的副本创建一个tensor
# 接口 一个空张量tensor可以通过规定其大小来构建
class torch.Tensor
class torch.Tensor(*sizes)
class torch.Tensor(size)
class torch.Tensor(sequence)
class torch.Tensor(ndarray)
class torch.Tensor(tensor)
class torch.Tensor(storage)
# 实例化
torch.IntTensor(2, 4).zero_()
可以用python的索引和切片来获取和修改一个张量tensor中的内容
x = torch.FloatTensor([[1, 2, 3], [4, 5, 6]])
x[1][2]
Out[0]: tensor(6.)
x[0][1] = 8
x
Out[1]:
tensor([[1., 8., 3.],
[4., 5., 6.]])
每一个张量tensor都有一个相应的torch.Storage
用来保存其数据。类tensor提供了一个存储的多维的、横向视图,并且定义了在数值运算
会改变tensor的函数操作会用一个下划线后缀来标示。比如,torch.FloatTensor.abs_()
会在原地计算绝对值,并返回改变后的tensor,而tensor.FloatTensor.abs()
将会在一个新的tensor中计算结果
关键属性和方法
Tensor.new_tensor |
Returns a new Tensor with data as the tensor data. |
---|---|
Tensor.new_full |
Returns a Tensor of size size filled with fill_value . |
Tensor.new_empty |
Returns a Tensor of size size filled with uninitialized data. |
Tensor.new_ones |
Returns a Tensor of size size filled with 1 . |
Tensor.new_zeros |
Returns a Tensor of size size filled with 0 . |
Tensor.is_cuda |
Is True if the Tensor is stored on the GPU, False otherwise. |
Tensor.is_quantized |
Is True if the Tensor is quantized, False otherwise. |
Tensor.is_meta |
Is True if the Tensor is a meta tensor, False otherwise. |
Tensor.device |
Is the torch.device where this Tensor is. |
Tensor.grad |
This attribute is None by default and becomes a Tensor the first time a call to backward() computes gradients for self . |
Tensor.ndim |
Alias for dim() |
Tensor.real |
Returns a new tensor containing real values of the self tensor for a complex-valued input tensor. |
Tensor.imag |
Returns a new tensor containing imaginary values of the self tensor. |
Tensor.abs |
See torch.abs() |
Tensor.abs_ |
In-place version of abs() |
Tensor.absolute |
Alias for abs() |
Tensor.absolute_ |
In-place version of absolute() Alias for abs_() |
Tensor.acos |
See torch.acos() |
Tensor.acos_ |
In-place version of acos() |
Tensor.arccos |
See torch.arccos() |
Tensor.arccos_ |
In-place version of arccos() |
Tensor.add |
Add a scalar or tensor to self tensor. |
Tensor.add_ |
In-place version of add() |
Tensor.addbmm |
See torch.addbmm() |
Tensor.addbmm_ |
In-place version of addbmm() |
Tensor.addcdiv |
See torch.addcdiv() |
Tensor.addcdiv_ |
In-place version of addcdiv() |
Tensor.addcmul |
See torch.addcmul() |
Tensor.addcmul_ |
In-place version of addcmul() |
Tensor.addmm |
See torch.addmm() |
Tensor.addmm_ |
In-place version of addmm() |
Tensor.sspaddmm |
See torch.sspaddmm() |
Tensor.addmv |
See torch.addmv() |
Tensor.addmv_ |
In-place version of addmv() |
Tensor.addr |
See torch.addr() |
Tensor.addr_ |
In-place version of addr() |
Tensor.adjoint |
Alias for adjoint() |
Tensor.allclose |
See torch.allclose() |
Tensor.amax |
See torch.amax() |
Tensor.amin |
See torch.amin() |
Tensor.aminmax |
See torch.aminmax() |
Tensor.angle |
See torch.angle() |
Tensor.apply_ |
Applies the function callable to each element in the tensor, replacing each element with the value returned by callable . |
Tensor.argmax |
See torch.argmax() |
Tensor.argmin |
See torch.argmin() |
Tensor.argsort |
See torch.argsort() |
Tensor.argwhere |
See torch.argwhere() |
Tensor.asin |
See torch.asin() |
Tensor.asin_ |
In-place version of asin() |
Tensor.arcsin |
See torch.arcsin() |
Tensor.arcsin_ |
In-place version of arcsin() |
Tensor.as_strided |
See torch.as_strided() |
Tensor.atan |
See torch.atan() |
Tensor.atan_ |
In-place version of atan() |
Tensor.arctan |
See torch.arctan() |
Tensor.arctan_ |
In-place version of arctan() |
Tensor.atan2 |
See torch.atan2() |
Tensor.atan2_ |
In-place version of atan2() |
Tensor.arctan2 |
See torch.arctan2() |
Tensor.arctan2_ |
atan2_(other) -> Tensor |
Tensor.all |
See torch.all() |
Tensor.any |
See torch.any() |
Tensor.backward |
Computes the gradient of current tensor w.r.t. |
Tensor.baddbmm |
See torch.baddbmm() |
Tensor.baddbmm_ |
In-place version of baddbmm() |
Tensor.bernoulli |
Returns a result tensor where each \texttt{result[i]}result[i] is independently sampled from \text{Bernoulli}(\texttt{self[i]})Bernoulli(self[i]). |
Tensor.bernoulli_ |
Fills each location of self with an independent sample from \text{Bernoulli}(\texttt{p})Bernoulli(p). |
Tensor.bfloat16 |
self.bfloat16() is equivalent to self.to(torch.bfloat16) . |
Tensor.bincount |
See torch.bincount() |
Tensor.bitwise_not |
See torch.bitwise_not() |
Tensor.bitwise_not_ |
In-place version of bitwise_not() |
Tensor.bitwise_and |
See torch.bitwise_and() |
Tensor.bitwise_and_ |
In-place version of bitwise_and() |
Tensor.bitwise_or |
See torch.bitwise_or() |
Tensor.bitwise_or_ |
In-place version of bitwise_or() |
Tensor.bitwise_xor |
See torch.bitwise_xor() |
Tensor.bitwise_xor_ |
In-place version of bitwise_xor() |
Tensor.bitwise_left_shift |
See torch.bitwise_left_shift() |
Tensor.bitwise_left_shift_ |
In-place version of bitwise_left_shift() |
Tensor.bitwise_right_shift |
See torch.bitwise_right_shift() |
Tensor.bitwise_right_shift_ |
In-place version of bitwise_right_shift() |
Tensor.bmm |
See torch.bmm() |
Tensor.bool |
self.bool() is equivalent to self.to(torch.bool) . |
Tensor.byte |
self.byte() is equivalent to self.to(torch.uint8) . |
Tensor.broadcast_to |
See torch.broadcast_to() . |
Tensor.cauchy_ |
Fills the tensor with numbers drawn from the Cauchy distribution: |
Tensor.ceil |
See torch.ceil() |
Tensor.ceil_ |
In-place version of ceil() |
Tensor.char |
self.char() is equivalent to self.to(torch.int8) . |
Tensor.cholesky |
See torch.cholesky() |
Tensor.cholesky_inverse |
See torch.cholesky_inverse() |
Tensor.cholesky_solve |
See torch.cholesky_solve() |
Tensor.chunk |
See torch.chunk() |
Tensor.clamp |
See torch.clamp() |
Tensor.clamp_ |
In-place version of clamp() |
Tensor.clip |
Alias for clamp() . |
Tensor.clip_ |
Alias for clamp_() . |
Tensor.clone |
See torch.clone() |
Tensor.contiguous |
Returns a contiguous in memory tensor containing the same data as self tensor. |
Tensor.copy_ |
Copies the elements from src into self tensor and returns self . |
Tensor.conj |
See torch.conj() |
Tensor.conj_physical |
See torch.conj_physical() |
Tensor.conj_physical_ |
In-place version of conj_physical() |
Tensor.resolve_conj |
See torch.resolve_conj() |
Tensor.resolve_neg |
See torch.resolve_neg() |
Tensor.copysign |
See torch.copysign() |
Tensor.copysign_ |
In-place version of copysign() |
Tensor.cos |
See torch.cos() |
Tensor.cos_ |
In-place version of cos() |
Tensor.cosh |
See torch.cosh() |
Tensor.cosh_ |
In-place version of cosh() |
Tensor.corrcoef |
See torch.corrcoef() |
Tensor.count_nonzero |
See torch.count_nonzero() |
Tensor.cov |
See torch.cov() |
Tensor.acosh |
See torch.acosh() |
Tensor.acosh_ |
In-place version of acosh() |
Tensor.arccosh |
acosh() -> Tensor |
Tensor.arccosh_ |
acosh_() -> Tensor |
Tensor.cpu |
Returns a copy of this object in CPU memory. |
Tensor.cross |
See torch.cross() |
Tensor.cuda |
Returns a copy of this object in CUDA memory. |
Tensor.logcumsumexp |
See torch.logcumsumexp() |
Tensor.cummax |
See torch.cummax() |
Tensor.cummin |
See torch.cummin() |
Tensor.cumprod |
See torch.cumprod() |
Tensor.cumprod_ |
In-place version of cumprod() |
Tensor.cumsum |
See torch.cumsum() |
Tensor.cumsum_ |
In-place version of cumsum() |
Tensor.chalf |
self.chalf() is equivalent to self.to(torch.complex32) . |
Tensor.cfloat |
self.cfloat() is equivalent to self.to(torch.complex64) . |
Tensor.cdouble |
self.cdouble() is equivalent to self.to(torch.complex128) . |
Tensor.data_ptr |
Returns the address of the first element of self tensor. |
Tensor.deg2rad |
See torch.deg2rad() |
Tensor.dequantize |
Given a quantized Tensor, dequantize it and return the dequantized float Tensor. |
Tensor.det |
See torch.det() |
Tensor.dense_dim |
Return the number of dense dimensions in a sparse tensor self . |
Tensor.detach |
Returns a new Tensor, detached from the current graph. |
Tensor.detach_ |
Detaches the Tensor from the graph that created it, making it a leaf. |
Tensor.diag |
See torch.diag() |
Tensor.diag_embed |
See torch.diag_embed() |
Tensor.diagflat |
See torch.diagflat() |
Tensor.diagonal |
See torch.diagonal() |
Tensor.diagonal_scatter |
See torch.diagonal_scatter() |
Tensor.fill_diagonal_ |
Fill the main diagonal of a tensor that has at least 2-dimensions. |
Tensor.fmax |
See torch.fmax() |
Tensor.fmin |
See torch.fmin() |
Tensor.diff |
See torch.diff() |
Tensor.digamma |
See torch.digamma() |
Tensor.digamma_ |
In-place version of digamma() |
Tensor.dim |
Returns the number of dimensions of self tensor. |
Tensor.dist |
See torch.dist() |
Tensor.div |
See torch.div() |
Tensor.div_ |
In-place version of div() |
Tensor.divide |
See torch.divide() |
Tensor.divide_ |
In-place version of divide() |
Tensor.dot |
See torch.dot() |
Tensor.double |
self.double() is equivalent to self.to(torch.float64) . |
Tensor.dsplit |
See torch.dsplit() |
Tensor.element_size |
Returns the size in bytes of an individual element. |
Tensor.eq |
See torch.eq() |
Tensor.eq_ |
In-place version of eq() |
Tensor.equal |
See torch.equal() |
Tensor.erf |
See torch.erf() |
Tensor.erf_ |
In-place version of erf() |
Tensor.erfc |
See torch.erfc() |
Tensor.erfc_ |
In-place version of erfc() |
Tensor.erfinv |
See torch.erfinv() |
Tensor.erfinv_ |
In-place version of erfinv() |
Tensor.exp |
See torch.exp() |
Tensor.exp_ |
In-place version of exp() |
Tensor.expm1 |
See torch.expm1() |
Tensor.expm1_ |
In-place version of expm1() |
Tensor.expand |
Returns a new view of the self tensor with singleton dimensions expanded to a larger size. |
Tensor.expand_as |
Expand this tensor to the same size as other . |
Tensor.exponential_ |
Fills self tensor with elements drawn from the exponential distribution: |
Tensor.fix |
See torch.fix() . |
Tensor.fix_ |
In-place version of fix() |
Tensor.fill_ |
Fills self tensor with the specified value. |
Tensor.flatten |
See torch.flatten() |
Tensor.flip |
See torch.flip() |
Tensor.fliplr |
See torch.fliplr() |
Tensor.flipud |
See torch.flipud() |
Tensor.float |
self.float() is equivalent to self.to(torch.float32) . |
Tensor.float_power |
See torch.float_power() |
Tensor.float_power_ |
In-place version of float_power() |
Tensor.floor |
See torch.floor() |
Tensor.floor_ |
In-place version of floor() |
Tensor.floor_divide |
See torch.floor_divide() |
Tensor.floor_divide_ |
In-place version of floor_divide() |
Tensor.fmod |
See torch.fmod() |
Tensor.fmod_ |
In-place version of fmod() |
Tensor.frac |
See torch.frac() |
Tensor.frac_ |
In-place version of frac() |
Tensor.frexp |
See torch.frexp() |
Tensor.gather |
See torch.gather() |
Tensor.gcd |
See torch.gcd() |
Tensor.gcd_ |
In-place version of gcd() |
Tensor.ge |
See torch.ge() . |
Tensor.ge_ |
In-place version of ge() . |
Tensor.greater_equal |
See torch.greater_equal() . |
Tensor.greater_equal_ |
In-place version of greater_equal() . |
Tensor.geometric_ |
Fills self tensor with elements drawn from the geometric distribution: |
Tensor.geqrf |
See torch.geqrf() |
Tensor.ger |
See torch.ger() |
Tensor.get_device |
For CUDA tensors, this function returns the device ordinal of the GPU on which the tensor resides. |
Tensor.gt |
See torch.gt() . |
Tensor.gt_ |
In-place version of gt() . |
Tensor.greater |
See torch.greater() . |
Tensor.greater_ |
In-place version of greater() . |
Tensor.half |
self.half() is equivalent to self.to(torch.float16) . |
Tensor.hardshrink |
See torch.nn.functional.hardshrink() |
Tensor.heaviside |
See torch.heaviside() |
Tensor.histc |
See torch.histc() |
Tensor.histogram |
See torch.histogram() |
Tensor.hsplit |
See torch.hsplit() |
Tensor.hypot |
See torch.hypot() |
Tensor.hypot_ |
In-place version of hypot() |
Tensor.i0 |
See torch.i0() |
Tensor.i0_ |
In-place version of i0() |
Tensor.igamma |
See torch.igamma() |
Tensor.igamma_ |
In-place version of igamma() |
Tensor.igammac |
See torch.igammac() |
Tensor.igammac_ |
In-place version of igammac() |
Tensor.index_add_ |
Accumulate the elements of alpha times source into the self tensor by adding to the indices in the order given in index . |
Tensor.index_add |
Out-of-place version of torch.Tensor.index_add_() . |
Tensor.index_copy_ |
Copies the elements of tensor into the self tensor by selecting the indices in the order given in index . |
Tensor.index_copy |
Out-of-place version of torch.Tensor.index_copy_() . |
Tensor.index_fill_ |
Fills the elements of the self tensor with value value by selecting the indices in the order given in index . |
Tensor.index_fill |
Out-of-place version of torch.Tensor.index_fill_() . |
Tensor.index_put_ |
Puts values from the tensor values into the tensor self using the indices specified in indices (which is a tuple of Tensors). |
Tensor.index_put |
Out-place version of index_put_() . |
Tensor.index_reduce_ |
Accumulate the elements of source into the self tensor by accumulating to the indices in the order given in index using the reduction given by the reduce argument. |
Tensor.index_reduce |
|
Tensor.index_select |
See torch.index_select() |
Tensor.indices |
Return the indices tensor of a sparse COO tensor. |
Tensor.inner |
See torch.inner() . |
Tensor.int |
self.int() is equivalent to self.to(torch.int32) . |
Tensor.int_repr |
Given a quantized Tensor, self.int_repr() returns a CPU Tensor with uint8_t as data type that stores the underlying uint8_t values of the given Tensor. |
Tensor.inverse |
See torch.inverse() |
Tensor.isclose |
See torch.isclose() |
Tensor.isfinite |
See torch.isfinite() |
Tensor.isinf |
See torch.isinf() |
Tensor.isposinf |
See torch.isposinf() |
Tensor.isneginf |
See torch.isneginf() |
Tensor.isnan |
See torch.isnan() |
Tensor.is_contiguous |
Returns True if self tensor is contiguous in memory in the order specified by memory format. |
Tensor.is_complex |
Returns True if the data type of self is a complex data type. |
Tensor.is_conj |
Returns True if the conjugate bit of self is set to true. |
Tensor.is_floating_point |
Returns True if the data type of self is a floating point data type. |
Tensor.is_inference |
See torch.is_inference() |
Tensor.is_leaf |
All Tensors that have requires_grad which is False will be leaf Tensors by convention. |
Tensor.is_pinned |
Returns true if this tensor resides in pinned memory. |
Tensor.is_set_to |
Returns True if both tensors are pointing to the exact same memory (same storage, offset, size and stride). |
Tensor.is_shared |
Checks if tensor is in shared memory. |
Tensor.is_signed |
Returns True if the data type of self is a signed data type. |
Tensor.is_sparse |
Is True if the Tensor uses sparse storage layout, False otherwise. |
Tensor.istft |
See torch.istft() |
Tensor.isreal |
See torch.isreal() |
Tensor.item |
Returns the value of this tensor as a standard Python number. |
Tensor.kthvalue |
See torch.kthvalue() |
Tensor.lcm |
See torch.lcm() |
Tensor.lcm_ |
In-place version of lcm() |
Tensor.ldexp |
See torch.ldexp() |
Tensor.ldexp_ |
In-place version of ldexp() |
Tensor.le |
See torch.le() . |
Tensor.le_ |
In-place version of le() . |
Tensor.less_equal |
See torch.less_equal() . |
Tensor.less_equal_ |
In-place version of less_equal() . |
Tensor.lerp |
See torch.lerp() |
Tensor.lerp_ |
In-place version of lerp() |
Tensor.lgamma |
See torch.lgamma() |
Tensor.lgamma_ |
In-place version of lgamma() |
Tensor.log |
See torch.log() |
Tensor.log_ |
In-place version of log() |
Tensor.logdet |
See torch.logdet() |
Tensor.log10 |
See torch.log10() |
Tensor.log10_ |
In-place version of log10() |
Tensor.log1p |
See torch.log1p() |
Tensor.log1p_ |
In-place version of log1p() |
Tensor.log2 |
See torch.log2() |
Tensor.log2_ |
In-place version of log2() |
Tensor.log_normal_ |
Fills self tensor with numbers samples from the log-normal distribution parameterized by the given mean \muμ and standard deviation \sigmaσ. |
Tensor.logaddexp |
See torch.logaddexp() |
Tensor.logaddexp2 |
See torch.logaddexp2() |
Tensor.logsumexp |
See torch.logsumexp() |
Tensor.logical_and |
See torch.logical_and() |
Tensor.logical_and_ |
In-place version of logical_and() |
Tensor.logical_not |
See torch.logical_not() |
Tensor.logical_not_ |
In-place version of logical_not() |
Tensor.logical_or |
See torch.logical_or() |
Tensor.logical_or_ |
In-place version of logical_or() |
Tensor.logical_xor |
See torch.logical_xor() |
Tensor.logical_xor_ |
In-place version of logical_xor() |
Tensor.logit |
See torch.logit() |
Tensor.logit_ |
In-place version of logit() |
Tensor.long |
self.long() is equivalent to self.to(torch.int64) . |
Tensor.lt |
See torch.lt() . |
Tensor.lt_ |
In-place version of lt() . |
Tensor.less |
lt(other) -> Tensor |
Tensor.less_ |
In-place version of less() . |
Tensor.lu |
See torch.lu() |
Tensor.lu_solve |
See torch.lu_solve() |
Tensor.as_subclass |
Makes a cls instance with the same data pointer as self . |
Tensor.map_ |
Applies callable for each element in self tensor and the given tensor and stores the results in self tensor. |
Tensor.masked_scatter_ |
Copies elements from source into self tensor at positions where the mask is True. |
Tensor.masked_scatter |
Out-of-place version of torch.Tensor.masked_scatter_() |
Tensor.masked_fill_ |
Fills elements of self tensor with value where mask is True. |
Tensor.masked_fill |
Out-of-place version of torch.Tensor.masked_fill_() |
Tensor.masked_select |
See torch.masked_select() |
Tensor.matmul |
See torch.matmul() |
Tensor.matrix_power |
NOTEmatrix_power() is deprecated, use torch.linalg.matrix_power() instead. |
Tensor.matrix_exp |
See torch.matrix_exp() |
Tensor.max |
See torch.max() |
Tensor.maximum |
See torch.maximum() |
Tensor.mean |
See torch.mean() |
Tensor.nanmean |
See torch.nanmean() |
Tensor.median |
See torch.median() |
Tensor.nanmedian |
See torch.nanmedian() |
Tensor.min |
See torch.min() |
Tensor.minimum |
See torch.minimum() |
Tensor.mm |
See torch.mm() |
Tensor.smm |
See torch.smm() |
Tensor.mode |
See torch.mode() |
Tensor.movedim |
See torch.movedim() |
Tensor.moveaxis |
See torch.moveaxis() |
Tensor.msort |
See torch.msort() |
Tensor.mul |
See torch.mul() . |
Tensor.mul_ |
In-place version of mul() . |
Tensor.multiply |
See torch.multiply() . |
Tensor.multiply_ |
In-place version of multiply() . |
Tensor.multinomial |
See torch.multinomial() |
Tensor.mv |
See torch.mv() |
Tensor.mvlgamma |
See torch.mvlgamma() |
Tensor.mvlgamma_ |
In-place version of mvlgamma() |
Tensor.nansum |
See torch.nansum() |
Tensor.narrow |
See torch.narrow() |
Tensor.narrow_copy |
See torch.narrow_copy() . |
Tensor.ndimension |
Alias for dim() |
Tensor.nan_to_num |
See torch.nan_to_num() . |
Tensor.nan_to_num_ |
In-place version of nan_to_num() . |
Tensor.ne |
See torch.ne() . |
Tensor.ne_ |
In-place version of ne() . |
Tensor.not_equal |
See torch.not_equal() . |
Tensor.not_equal_ |
In-place version of not_equal() . |
Tensor.neg |
See torch.neg() |
Tensor.neg_ |
In-place version of neg() |
Tensor.negative |
See torch.negative() |
Tensor.negative_ |
In-place version of negative() |
Tensor.nelement |
Alias for numel() |
Tensor.nextafter |
See torch.nextafter() |
Tensor.nextafter_ |
In-place version of nextafter() |
Tensor.nonzero |
See torch.nonzero() |
Tensor.norm |
See torch.norm() |
Tensor.normal_ |
Fills self tensor with elements samples from the normal distribution parameterized by mean and std . |
Tensor.numel |
See torch.numel() |
Tensor.numpy |
Returns the tensor as a NumPy ndarray . |
Tensor.orgqr |
See torch.orgqr() |
Tensor.ormqr |
See torch.ormqr() |
Tensor.outer |
See torch.outer() . |
Tensor.permute |
See torch.permute() |
Tensor.pin_memory |
Copies the tensor to pinned memory, if it's not already pinned. |
Tensor.pinverse |
See torch.pinverse() |
Tensor.polygamma |
See torch.polygamma() |
Tensor.polygamma_ |
In-place version of polygamma() |
Tensor.positive |
See torch.positive() |
Tensor.pow |
See torch.pow() |
Tensor.pow_ |
In-place version of pow() |
Tensor.prod |
See torch.prod() |
Tensor.put_ |
Copies the elements from source into the positions specified by index . |
Tensor.qr |
See torch.qr() |
Tensor.qscheme |
Returns the quantization scheme of a given QTensor. |
Tensor.quantile |
See torch.quantile() |
Tensor.nanquantile |
See torch.nanquantile() |
Tensor.q_scale |
Given a Tensor quantized by linear(affine) quantization, returns the scale of the underlying quantizer(). |
Tensor.q_zero_point |
Given a Tensor quantized by linear(affine) quantization, returns the zero_point of the underlying quantizer(). |
Tensor.q_per_channel_scales |
Given a Tensor quantized by linear (affine) per-channel quantization, returns a Tensor of scales of the underlying quantizer. |
Tensor.q_per_channel_zero_points |
Given a Tensor quantized by linear (affine) per-channel quantization, returns a tensor of zero_points of the underlying quantizer. |
Tensor.q_per_channel_axis |
Given a Tensor quantized by linear (affine) per-channel quantization, returns the index of dimension on which per-channel quantization is applied. |
Tensor.rad2deg |
See torch.rad2deg() |
Tensor.random_ |
Fills self tensor with numbers sampled from the discrete uniform distribution over [from, to - 1] . |
Tensor.ravel |
see torch.ravel() |
Tensor.reciprocal |
See torch.reciprocal() |
Tensor.reciprocal_ |
In-place version of reciprocal() |
Tensor.record_stream |
Ensures that the tensor memory is not reused for another tensor until all current work queued on stream are complete. |
Tensor.register_hook |
Registers a backward hook. |
Tensor.remainder |
See torch.remainder() |
Tensor.remainder_ |
In-place version of remainder() |
Tensor.renorm |
See torch.renorm() |
Tensor.renorm_ |
In-place version of renorm() |
Tensor.repeat |
Repeats this tensor along the specified dimensions. |
Tensor.repeat_interleave |
See torch.repeat_interleave() . |
Tensor.requires_grad |
Is True if gradients need to be computed for this Tensor, False otherwise. |
Tensor.requires_grad_ |
Change if autograd should record operations on this tensor: sets this tensor's requires_grad attribute in-place. |
Tensor.reshape |
Returns a tensor with the same data and number of elements as self but with the specified shape. |
Tensor.reshape_as |
Returns this tensor as the same shape as other . |
Tensor.resize_ |
Resizes self tensor to the specified size. |
Tensor.resize_as_ |
Resizes the self tensor to be the same size as the specified tensor . |
Tensor.retain_grad |
Enables this Tensor to have their grad populated during backward() . |
Tensor.retains_grad |
Is True if this Tensor is non-leaf and its grad is enabled to be populated during backward() , False otherwise. |
Tensor.roll |
See torch.roll() |
Tensor.rot90 |
See torch.rot90() |
Tensor.round |
See torch.round() |
Tensor.round_ |
In-place version of round() |
Tensor.rsqrt |
See torch.rsqrt() |
Tensor.rsqrt_ |
In-place version of rsqrt() |
Tensor.scatter |
Out-of-place version of torch.Tensor.scatter_() |
Tensor.scatter_ |
Writes all values from the tensor src into self at the indices specified in the index tensor. |
Tensor.scatter_add_ |
Adds all values from the tensor src into self at the indices specified in the index tensor in a similar fashion as scatter_() . |
Tensor.scatter_add |
Out-of-place version of torch.Tensor.scatter_add_() |
Tensor.scatter_reduce_ |
Reduces all values from the src tensor to the indices specified in the index tensor in the self tensor using the applied reduction defined via the reduce argument ("sum" , "prod" , "mean" , "amax" , "amin" ). |
Tensor.scatter_reduce |
Out-of-place version of torch.Tensor.scatter_reduce_() |
Tensor.select |
See torch.select() |
Tensor.select_scatter |
See torch.select_scatter() |
Tensor.set_ |
Sets the underlying storage, size, and strides. |
Tensor.share_memory_ |
Moves the underlying storage to shared memory. |
Tensor.short |
self.short() is equivalent to self.to(torch.int16) . |
Tensor.sigmoid |
See torch.sigmoid() |
Tensor.sigmoid_ |
In-place version of sigmoid() |
Tensor.sign |
See torch.sign() |
Tensor.sign_ |
In-place version of sign() |
Tensor.signbit |
See torch.signbit() |
Tensor.sgn |
See torch.sgn() |
Tensor.sgn_ |
In-place version of sgn() |
Tensor.sin |
See torch.sin() |
Tensor.sin_ |
In-place version of sin() |
Tensor.sinc |
See torch.sinc() |
Tensor.sinc_ |
In-place version of sinc() |
Tensor.sinh |
See torch.sinh() |
Tensor.sinh_ |
In-place version of sinh() |
Tensor.asinh |
See torch.asinh() |
Tensor.asinh_ |
In-place version of asinh() |
Tensor.arcsinh |
See torch.arcsinh() |
Tensor.arcsinh_ |
In-place version of arcsinh() |
Tensor.size |
Returns the size of the self tensor. |
Tensor.slogdet |
See torch.slogdet() |
Tensor.slice_scatter |
See torch.slice_scatter() |
Tensor.sort |
See torch.sort() |
Tensor.split |
See torch.split() |
Tensor.sparse_mask |
Returns a new sparse tensor with values from a strided tensor self filtered by the indices of the sparse tensor mask . |
Tensor.sparse_dim |
Return the number of sparse dimensions in a sparse tensor self . |
Tensor.sqrt |
See torch.sqrt() |
Tensor.sqrt_ |
In-place version of sqrt() |
Tensor.square |
See torch.square() |
Tensor.square_ |
In-place version of square() |
Tensor.squeeze |
See torch.squeeze() |
Tensor.squeeze_ |
In-place version of squeeze() |
Tensor.std |
See torch.std() |
Tensor.stft |
See torch.stft() |
Tensor.storage |
Returns the underlying storage. |
Tensor.storage_offset |
Returns self tensor's offset in the underlying storage in terms of number of storage elements (not bytes). |
Tensor.storage_type |
Returns the type of the underlying storage. |
Tensor.stride |
Returns the stride of self tensor. |
Tensor.sub |
See torch.sub() . |
Tensor.sub_ |
In-place version of sub() |
Tensor.subtract |
See torch.subtract() . |
Tensor.subtract_ |
In-place version of subtract() . |
Tensor.sum |
See torch.sum() |
Tensor.sum_to_size |
Sum this tensor to size . |
Tensor.svd |
See torch.svd() |
Tensor.swapaxes |
See torch.swapaxes() |
Tensor.swapdims |
See torch.swapdims() |
Tensor.symeig |
See torch.symeig() |
Tensor.t |
See torch.t() |
Tensor.t_ |
In-place version of t() |
Tensor.tensor_split |
See torch.tensor_split() |
Tensor.tile |
See torch.tile() |
Tensor.to |
Performs Tensor dtype and/or device conversion. |
Tensor.to_mkldnn |
Returns a copy of the tensor in torch.mkldnn layout. |
Tensor.take |
See torch.take() |
Tensor.take_along_dim |
See torch.take_along_dim() |
Tensor.tan |
See torch.tan() |
Tensor.tan_ |
In-place version of tan() |
Tensor.tanh |
See torch.tanh() |
Tensor.tanh_ |
In-place version of tanh() |
Tensor.atanh |
See torch.atanh() |
Tensor.atanh_ |
In-place version of atanh() |
Tensor.arctanh |
See torch.arctanh() |
Tensor.arctanh_ |
In-place version of arctanh() |
Tensor.tolist |
Returns the tensor as a (nested) list. |
Tensor.topk |
See torch.topk() |
Tensor.to_dense |
Creates a strided copy of self if self is not a strided tensor, otherwise returns self . |
Tensor.to_sparse |
Returns a sparse copy of the tensor. |
Tensor.to_sparse_csr |
Convert a tensor to compressed row storage format (CSR). |
Tensor.to_sparse_csc |
Convert a tensor to compressed column storage (CSC) format. |
Tensor.to_sparse_bsr |
Convert a CSR tensor to a block sparse row (BSR) storage format of given blocksize. |
Tensor.to_sparse_bsc |
Convert a CSR tensor to a block sparse column (BSC) storage format of given blocksize. |
Tensor.trace |
See torch.trace() |
Tensor.transpose |
See torch.transpose() |
Tensor.transpose_ |
In-place version of transpose() |
Tensor.triangular_solve |
See torch.triangular_solve() |
Tensor.tril |
See torch.tril() |
Tensor.tril_ |
In-place version of tril() |
Tensor.triu |
See torch.triu() |
Tensor.triu_ |
In-place version of triu() |
Tensor.true_divide |
See torch.true_divide() |
Tensor.true_divide_ |
In-place version of true_divide_() |
Tensor.trunc |
See torch.trunc() |
Tensor.trunc_ |
In-place version of trunc() |
Tensor.type |
Returns the type if dtype is not provided, else casts this object to the specified type. |
Tensor.type_as |
Returns this tensor cast to the type of the given tensor. |
Tensor.unbind |
See torch.unbind() |
Tensor.unflatten |
See torch.unflatten() . |
Tensor.unfold |
Returns a view of the original tensor which contains all slices of size size from self tensor in the dimension dimension . |
Tensor.uniform_ |
Fills self tensor with numbers sampled from the continuous uniform distribution: |
Tensor.unique |
Returns the unique elements of the input tensor. |
Tensor.unique_consecutive |
Eliminates all but the first element from every consecutive group of equivalent elements. |
Tensor.unsqueeze |
See torch.unsqueeze() |
Tensor.unsqueeze_ |
In-place version of unsqueeze() |
Tensor.values |
Return the values tensor of a sparse COO tensor. |
Tensor.var |
See torch.var() |
Tensor.vdot |
See torch.vdot() |
Tensor.view |
Returns a new tensor with the same data as the self tensor but of a different shape . |
Tensor.view_as |
View this tensor as the same size as other . |
Tensor.vsplit |
See torch.vsplit() |
Tensor.where |
self.where(condition, y) is equivalent to torch.where(condition, self, y) . |
Tensor.xlogy |
See torch.xlogy() |
Tensor.xlogy_ |
In-place version of xlogy() |
Tensor.zero_ |
Fills self tensor with zeros. |
1.1 storage
pytorch中一个tensor对象分为头信息区(Tensor)和存储区(Storage)两部分
头信息区主要保存tensor的形状(size)、步长(stride)、数据类型(type)等信息;而真正的data(数据)则以连续一维数组的形式放在存储区,由torch.Storage实例管理着
注意:storage永远是一维数组,任何维度的tensor的实际数据都存储在一维的storage中
获取tensor的storage
a = torch.tensor([[1.0, 4.0],[2.0, 1.0],[3.0, 5.0]])
a.storage()
Out[0]:
1.0
4.0
2.0
1.0
3.0
5.0
[torch.storage.TypedStorage(dtype=torch.float32, device=cpu) of size 6]
a.storage()[2] = 9
id(a.storage())
Out[1]: 1343354913168
2 实例
2.1 图片分类
2.1.1 Pytorch加载数据
Pytorch中加载数据需要Dataset、Dataloader。
- Dataset提供一种方式去获取每个数据及其对应的label,告诉我们总共有多少个数据。
- Dataloader为后面的网络提供不同的数据形式,它将一批一批数据进行一个打包。
2.1.2 Tensorboard
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 准备的测试数据集
test_data = torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor())
# batch_size=4 使得 img0, target0 = dataset[0]、img1, target1 = dataset[1]、img2, target2 = dataset[2]、img3, target3 = dataset[3],然后这四个数据作为Dataloader的一个返回
test_loader = DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0,drop_last=False)
# 用for循环取出DataLoader打包好的四个数据
writer = SummaryWriter("logs")
step = 0
for data in test_loader:
imgs, targets = data # 每个data都是由4张图片组成,imgs.size 为 [4,3,32,32],四张32×32图片三通道,targets由四个标签组成
writer.add_images("test_data",imgs,step)
step = step + 1
writer.close()
2.1.3 Transforms
① Transforms当成工具箱的话,里面的class就是不同的工具。例如像totensor、resize这些工具。
② Transforms拿一些特定格式的图片,经过Transforms里面的工具,获得我们想要的结果。
from torchvision import transforms
from PIL import Image
img_path = "Data/FirstTypeData/val/bees/10870992_eebeeb3a12.jpg"
img = Image.open(img_path)
tensor_trans = transforms.ToTensor() # 创建 transforms.ToTensor类 的实例化对象
tensor_img = tensor_trans(img) # 调用 transforms.ToTensor类 的__call__的魔术方法
print(tensor_img)
2.1.4 torchvision数据集
① torchvision中有很多数据集,当我们写代码时指定相应的数据集指定一些参数,它就可以自行下载。
② CIFAR-10数据集包含60000张32×32的彩色图片,一共10个类别,其中50000张训练图片,10000张测试图片。
import torchvision
train_set = torchvision.datasets.CIFAR10(root="./dataset",train=True,download=True) # root为存放数据集的相对路线
test_set = torchvision.datasets.CIFAR10(root="./dataset",train=False,download=True) # train=True是训练集,train=False是测试集
print(test_set[0]) # 输出的3是target
print(test_set.classes) # 测试数据集中有多少种
img, target = test_set[0] # 分别获得图片、target
print(img)
print(target)
print(test_set.classes[target]) # 3号target对应的种类
img.show()
2.1.5 损失函数
① Loss损失函数一方面计算实际输出和目标之间的差距。
② Loss损失函数另一方面为我们更新输出提供一定的依据
L1loss损失函数
import torch
from torch.nn import L1Loss
inputs = torch.tensor([1,2,3],dtype=torch.float32)
targets = torch.tensor([1,2,5],dtype=torch.float32)
inputs = torch.reshape(inputs,(1,1,1,3))
targets = torch.reshape(targets,(1,1,1,3))
loss = L1Loss() # 默认为 maen
result = loss(inputs,targets)
print(result)
MSE损失函数
import torch
from torch.nn import L1Loss
from torch import nn
inputs = torch.tensor([1,2,3],dtype=torch.float32)
targets = torch.tensor([1,2,5],dtype=torch.float32)
inputs = torch.reshape(inputs,(1,1,1,3))
targets = torch.reshape(targets,(1,1,1,3))
loss_mse = nn.MSELoss()
result_mse = loss_mse(inputs,targets)
print(result_mse)
交叉熵损失函数
import torch
from torch.nn import L1Loss
from torch import nn
x = torch.tensor([0.1,0.2,0.3])
y = torch.tensor([1])
x = torch.reshape(x,(1,3)) # 1的 batch_size,有三类
loss_cross = nn.CrossEntropyLoss()
result_cross = loss_cross(x,y)
print(result_cross)
2.1.6 优化器
① 损失函数调用backward方法,就可以调用损失函数的反向传播方法,就可以求出我们需要调节的梯度,我们就可以利用我们的优化器就可以根据梯度对参数进行调整,达到整体误差降低的目的。
② 梯度要清零,如果梯度不清零会导致梯度累加
loss = nn.CrossEntropyLoss() # 交叉熵
tudui = Tudui()
optim = torch.optim.SGD(tudui.parameters(),lr=0.01) # 随机梯度下降优化器
for data in dataloader:
imgs, targets = data
outputs = tudui(imgs)
result_loss = loss(outputs, targets) # 计算实际输出与目标输出的差距
optim.zero_grad() # 梯度清零
result_loss.backward() # 反向传播,计算损失函数的梯度
optim.step() # 根据梯度,对网络的参数进行调优
print(result_loss) # 对数据只看了一遍,只看了一轮,所以loss下降不大
神经网络学习率优化
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset, batch_size=64,drop_last=True)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.model1 = Sequential(
Conv2d(3,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,64,5,padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024,64),
Linear(64,10)
)
def forward(self, x):
x = self.model1(x)
return x
loss = nn.CrossEntropyLoss() # 交叉熵
tudui = Tudui()
optim = torch.optim.SGD(tudui.parameters(),lr=0.01) # 随机梯度下降优化器
scheduler = torch.optim.lr_scheduler.StepLR(optim, step_size=5, gamma=0.1) # 每过 step_size 更新一次优化器,更新是学习率为原来的学习率的 0.1 倍
for epoch in range(20):
running_loss = 0.0
for data in dataloader:
imgs, targets = data
outputs = tudui(imgs)
result_loss = loss(outputs, targets) # 计算实际输出与目标输出的差距
optim.zero_grad() # 梯度清零
result_loss.backward() # 反向传播,计算损失函数的梯度
optim.step() # 根据梯度,对网络的参数进行调优
scheduler.step() # 学习率太小了,所以20个轮次后,相当于没走多少
running_loss = running_loss + result_loss
print(running_loss) # 对这一轮所有误差的总和
2.1.7 网络模型使用及修改
网络模型添加
import torchvision
from torch import nn
dataset = torchvision.datasets.CIFAR10("./dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
vgg16_true = torchvision.models.vgg16(pretrained=True) # 下载卷积层对应的参数是多少、池化层对应的参数时多少,这些参数时ImageNet训练好了的
vgg16_true.add_module('add_linear',nn.Linear(1000,10)) # 在VGG16后面添加一个线性层,使得输出为适应CIFAR10的输出,CIFAR10需要输出10个种类
print(vgg16_true)
网络模型修改
import torchvision
from torch import nn
vgg16_false = torchvision.models.vgg16(pretrained=False) # 没有预训练的参数
print(vgg16_false)
vgg16_false.classifier[6] = nn.Linear(4096,10)
print(vgg16_false)
2.1.8 网络模型保存与读取
模型结构 + 模型参数
import torchvision
import torch
vgg16 = torchvision.models.vgg16(pretrained=False)
torch.save(vgg16,"./model/vgg16_method1.pth") # 保存方式一:模型结构 + 模型参数
print(vgg16)
model = torch.load("./model/vgg16_method1.pth") # 保存方式一对应的加载模型
print(model)
模型参数(官方推荐),不保存网络模型结构
import torchvision
import torch
vgg16 = torchvision.models.vgg16(pretrained=False)
torch.save(vgg16.state_dict(),"./model/vgg16_method2.pth") # 保存方式二:模型参数(官方推荐),不再保存网络模型结构
print(vgg16)
model = torch.load("./model/vgg16_method2.pth") # 导入模型参数
print(model)
2.1.9 固定模型参数
在训练过程中可能需要固定一部分模型的参数,只更新另一部分参数,有两种思路实现这个目标
- 一个是设置不要更新参数的网络层为false
- 另一个就是在定义优化器时只传入要更新的参数
当然最优的做法是,优化器中只传入requires_grad=True的参数,这样占用的内存会更小一点,效率也会更高
import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的网络
class net(nn.Module):
def __init__(self, num_class=3):
super(net, self).__init__()
self.fc1 = nn.Linear(8, 4)
self.fc2 = nn.Linear(4, num_class)
def forward(self, x):
return self.fc2(self.fc1(x))
model = net()
# 冻结fc1层的参数
for name, param in model.named_parameters():
if "fc1" in name:
param.requires_grad = False
loss_fn = nn.CrossEntropyLoss()
# 只传入requires_grad = True的参数
optimizer = optim.SGD(filter(lambda p: p.requires_grad, net.parameters(), lr=1e-2)
print("model.fc1.weight", model.fc1.weight)
print("model.fc2.weight", model.fc2.weight)
model.train()
for epoch in range(10):
x = torch.randn((3, 8))
label = torch.randint(0, 3, [3]).long()
output = model(x)
loss = loss_fn(output, label)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print("model.fc1.weight", model.fc1.weight)
print("model.fc2.weight", model.fc2.weight)
2.1.10 训练流程
DataLoader加载数据集
import torchvision
from torch import nn
from torch.utils.data import DataLoader
# 准备数据集
train_data = torchvision.datasets.CIFAR10("./dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
# length 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 如果train_data_size=10,则打印:训练数据集的长度为:10
print("训练数据集的长度:{}".format(train_data_size))
print("测试数据集的长度:{}".format(test_data_size))
# 利用 Dataloader 来加载数据集
train_dataloader = DataLoader(train_data_size, batch_size=64)
test_dataloader = DataLoader(test_data_size, batch_size=64)
测试网络正确
import torch
from torch import nn
# 搭建神经网络
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.model1 = nn.Sequential(
nn.Conv2d(3,32,5,1,2), # 输入通道3,输出通道32,卷积核尺寸5×5,步长1,填充2
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(), # 展平后变成 64*4*4 了
nn.Linear(64*4*4,64),
nn.Linear(64,10)
)
def forward(self, x):
x = self.model1(x)
return x
if __name__ == '__main__':
tudui = Tudui()
input = torch.ones((64,3,32,32))
output = tudui(input)
print(output.shape) # 测试输出的尺寸是不是我们想要的
网络训练数据
① model.train()和model.eval()的区别主要在于Batch Normalization和Dropout两层。
② 如果模型中有BN层(Batch Normalization)和 Dropout,需要在训练时添加model.train()。model.train()是保证BN层能够用到每一批数据的均值和方差。对于Dropout,model.train()是随机取一部分网络连接来训练更新参数。
③ 不启用 Batch Normalization 和 Dropout。 如果模型中有BN层(Batch Normalization)和Dropout,在测试时添加model.eval()。model.eval()是保证BN层能够用全部训练数据的均值和方差,即测试过程中要保证BN层的均值和方差不变。对于Dropout,model.eval()是利用到了所有网络连接,即不进行随机舍弃神经元。
④ 训练完train样本后,生成的模型model要用来测试样本。在model(test)之前,需要加上model.eval(),否则的话,有输入数据,即使不训练,它也会改变权值。这是model中含有BN层和Dropout所带来的性质。
⑤ 在做one classification的时候,训练集和测试集的样本分布是不一样的,尤其需要注意这一点
import torchvision
import torch
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# from model import * 相当于把 model中的所有内容写到这里,这里直接把 model 写在这里
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.model1 = nn.Sequential(
nn.Conv2d(3,32,5,1,2), # 输入通道3,输出通道32,卷积核尺寸5×5,步长1,填充2
nn.MaxPool2d(2),
nn.Conv2d(32,32,5,1,2),
nn.MaxPool2d(2),
nn.Conv2d(32,64,5,1,2),
nn.MaxPool2d(2),
nn.Flatten(), # 展平后变成 64*4*4 了
nn.Linear(64*4*4,64),
nn.Linear(64,10)
)
def forward(self, x):
x = self.model1(x)
return x
# 准备数据集
train_data = torchvision.datasets.CIFAR10("./dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
# length 长度
train_data_size = len(train_data)
test_data_size = len(test_data)
# 如果train_data_size=10,则打印:训练数据集的长度为:10
print("训练数据集的长度:{}".format(train_data_size))
print("测试数据集的长度:{}".format(test_data_size))
# 利用 Dataloader 来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
# 创建网络模型
tudui = Tudui()
# 损失函数
loss_fn = nn.CrossEntropyLoss() # 交叉熵,fn 是 fuction 的缩写
# 优化器
learning = 0.01 # 1e-2 就是 0.01 的意思
optimizer = torch.optim.SGD(tudui.parameters(),learning) # 随机梯度下降优化器
# 设置网络的一些参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮次
epoch = 10
# 添加 tensorboard
writer = SummaryWriter("logs")
for i in range(epoch):
print("-----第 {} 轮训练开始-----".format(i+1))
# 训练步骤开始
tudui.train() # 当网络中有dropout层、batchnorm层时,这些层能起作用
for data in train_dataloader:
imgs, targets = data
outputs = tudui(imgs)
loss = loss_fn(outputs, targets) # 计算实际输出与目标输出的差距
# 优化器对模型调优
optimizer.zero_grad() # 梯度清零
loss.backward() # 反向传播,计算损失函数的梯度
optimizer.step() # 根据梯度,对网络的参数进行调优
total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print("训练次数:{},Loss:{}".format(total_train_step,loss.item())) # 方式二:获得loss值
writer.add_scalar("train_loss",loss.item(),total_train_step)
# 测试步骤开始(每一轮训练后都查看在测试数据集上的loss情况)
tudui.eval() # 当网络中有dropout层、batchnorm层时,这些层不能起作用
total_test_loss = 0
total_accuracy = 0
with torch.no_grad(): # 没有梯度了
for data in test_dataloader: # 测试数据集提取数据
imgs, targets = data
outputs = tudui(imgs)
loss = loss_fn(outputs, targets) # 仅data数据在网络模型上的损失
total_test_loss = total_test_loss + loss.item() # 所有loss
accuracy = (outputs.argmax(1) == targets).sum()
total_accuracy = total_accuracy + accuracy
print("整体测试集上的Loss:{}".format(total_test_loss))
print("整体测试集上的正确率:{}".format(total_accuracy/test_data_size))
writer.add_scalar("test_loss",total_test_loss,total_test_step)
writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
total_test_step = total_test_step + 1
torch.save(tudui, "./model/tudui_{}.pth".format(i)) # 保存每一轮训练后的结果
#torch.save(tudui.state_dict(),"tudui_{}.path".format(i)) # 保存方式二
print("模型已保存")
writer.close()
2.2 迁移学习
2.2.1 模型|参数查看
import torch
class MyModel(torch.nn.Module):
def __init__(self):
super().__init__()
self.layer1 = torch.nn.Sequential(
torch.nn.Linear(3, 4),
torch.nn.Linear(4, 3),
)
self.layer2 = torch.nn.Linear(3, 6)
self.layer3 = torch.nn.Sequential(
torch.nn.Linear(6, 7),
torch.nn.Linear(7, 5),
)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
return x
net = MyModel()
print(net)
MyModel(
(layer1): Sequential(
(0): Linear(in_features=3, out_features=4, bias=True)
(1): Linear(in_features=4, out_features=3, bias=True)
)
(layer2): Linear(in_features=3, out_features=6, bias=True)
(layer3): Sequential(
(0): Linear(in_features=6, out_features=7, bias=True)
(1): Linear(in_features=7, out_features=5, bias=True)
)
)
查看参数
for layer in net.modules():
print(type(layer)) # 查看每一层的类型
# print(layer)
<class '__main__.MyModel'>
<class 'torch.nn.modules.container.Sequential'>
<class 'torch.nn.modules.linear.Linear'>
<class 'torch.nn.modules.linear.Linear'>
<class 'torch.nn.modules.linear.Linear'>
<class 'torch.nn.modules.container.Sequential'>
<class 'torch.nn.modules.linear.Linear'>
<class 'torch.nn.modules.linear.Linear'>
for param in net.parameters():
print(param.shape) # 打印每一层的参数
torch.Size([4, 3])
torch.Size([4])
torch.Size([3, 4])
torch.Size([3])
torch.Size([6, 3])
torch.Size([6])
torch.Size([7, 6])
torch.Size([7])
torch.Size([5, 7])
torch.Size([5])
for name, param in net.named_parameters():
print(name, param.shape) # 看的更细
layer1.0.weight torch.Size([4, 3])
layer1.0.bias torch.Size([4])
layer1.1.weight torch.Size([3, 4])
layer1.1.bias torch.Size([3])
layer2.weight torch.Size([6, 3])
layer2.bias torch.Size([6])
layer3.0.weight torch.Size([7, 6])
layer3.0.bias torch.Size([7])
layer3.1.weight torch.Size([5, 7])
layer3.1.bias torch.Size([5])
for key, value in net.state_dict().items(): # 参数名以及参数
print(key, value.shape)
layer1.0.weight torch.Size([4, 3])
layer1.0.bias torch.Size([4])
layer1.1.weight torch.Size([3, 4])
layer1.1.bias torch.Size([3])
layer2.weight torch.Size([6, 3])
layer2.bias torch.Size([6])
layer3.0.weight torch.Size([7, 6])
layer3.0.bias torch.Size([7])
layer3.1.weight torch.Size([5, 7])
layer3.1.bias torch.Size([5])
2.2.2 模型保存|加载
# 1、加载模型+参数
net = torch.load("resnet50.pth")
# 2、已有模型,加载预训练参数
resnet50 = models.resnet50(weights=None)
resnet50.load_state_dict(torch.load("resnet58_weight.pth"))
2.2.3 网络的修改
from torch import nn
from torchvision import models
alexnet = models.alexnet(weights=models.AlexNet_Weights.DEFAULT)
print(alexnet)
AlexNet(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Dropout(p=0.5, inplace=False)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Dropout(p=0.5, inplace=False)
(4): Linear(in_features=4096, out_features=4096, bias=True)
(5): ReLU(inplace=True)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
)
修改网络结构
# 1、-----删除网络的最后一层-----
# del alexnet.classifier
del alexnet.classifier[6]
print(alexnet)
AlexNet(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Dropout(p=0.5, inplace=False)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Dropout(p=0.5, inplace=False)
(4): Linear(in_features=4096, out_features=4096, bias=True)
(5): ReLU(inplace=True)
)
)
# 2、-----删除网络的最后多层-----
alexnet.classifier = alexnet.classifier[:-2]
print(alexnet)
AlexNet(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Dropout(p=0.5, inplace=False)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Dropout(p=0.5, inplace=False)
)
)
# 3、-----修改网络的某一层-----
alexnet.classifier[6] = nn.Linear(in_features=4096, out_features=1024)
print(alexnet)
AlexNet(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Dropout(p=0.5, inplace=False)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Linear(in_features=4096, out_features=1024, bias=True)
)
)
# 4、-----网络添加层,每次添加一层-----
alexnet.classifier.add_module('7', nn.ReLU(inplace=True))
alexnet.classifier.add_module('8', nn.Linear(in_features=1024, out_features=20))
print(alexnet)
AlexNet(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Dropout(p=0.5, inplace=False)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Linear(in_features=4096, out_features=1024, bias=True)
(4): ReLU(inplace=True)
(5): Linear(in_features=1024, out_features=20, bias=True)
)
)
2.2.4 参数冻结
# 任务一∶
# 1、将模型A作为backbone,修改为模型B
# 2、模型A的预训练参数加载到模型B上
resnet_modified = resnet50()
new_weights_dict = resnet_modified.state_dict()
resnet = models.resnet50(weights=models.ResNet50_Weights.DEFAULT)
weights_dict = resnet.state_dict()
for k in weights_dict.keys():
if k in new_weights_dict.keys() and not k.startswith('fc'):
new_weights_dict[k] = weights_dict[k]
resnet_modified.load_state_dict(new_weights_dict)
# resnet_modified.load_state_dict(new_weights_dict,strict=False)
# 任务二:
# 冻结与训练好的参数
params = []
train_layer = ['layer5', 'conv_end', 'bn_end']
for name, param in resnet_modified.named_parameters():
if any(name.startswith(prefix) for prefix in train_layer):
print(name)
params.append(param)
else:
param.requires_grad = False
optimizer = torch.optim.SGD(params, lr=0.001, momentum=0.9, weight_decay=5e-4)