Pytorch上下采样函数--interpolate用法
最近用到了上采样下采样操作,pytorch中使用interpolate可以很轻松的完成
definterpolate(input,size=None,scale_factor=None,mode='nearest',align_corners=None):
r"""
根据给定size或scale_factor,上采样或下采样输入数据input.
当前支持temporal,spatial和volumetric输入数据的上采样,其shape分别为:3-D,4-D和5-D.
输入数据的形式为:mini-batchxchannelsx[optionaldepth]x[optionalheight]xwidth.
上采样算法有:nearest,linear(3D-only),bilinear(4D-only),trilinear(5D-only).
参数:
-input(Tensor):inputtensor
-size(intorTuple[int]orTuple[int,int]orTuple[int,int,int]):输出的spatial尺寸.
-scale_factor(floatorTuple[float]):spatial尺寸的缩放因子.
-mode(string):上采样算法:nearest,linear,bilinear,trilinear,area.默认为nearest.
-align_corners(bool,optional):如果align_corners=True,则对齐input和output的角点像素(cornerpixels),保持在角点像素的值.只会对mode=linear,bilinear和trilinear有作用.默认是False.
"""
fromnumbersimportIntegral
from.modules.utilsimport_ntuple
def_check_size_scale_factor(dim):
ifsizeisNoneandscale_factorisNone:
raiseValueError('eithersizeorscale_factorshouldbedefined')
ifsizeisnotNoneandscale_factorisnotNone:
raiseValueError('onlyoneofsizeorscale_factorshouldbedefined')
ifscale_factorisnotNoneandisinstance(scale_factor,tuple)\
andlen(scale_factor)!=dim:
raiseValueError('scale_factorshapemustmatchinputshape.'
'Inputis{}D,scale_factorsizeis{}'.format(dim,len(scale_factor)))
def_output_size(dim):
_check_size_scale_factor(dim)
ifsizeisnotNone:
returnsize
scale_factors=_ntuple(dim)(scale_factor)
#math.floormightreturnfloatinpy2.7
return[int(math.floor(input.size(i+2)*scale_factors[i]))foriinrange(dim)]
ifmodein('nearest','area'):
ifalign_cornersisnotNone:
raiseValueError("align_cornersoptioncanonlybesetwiththe"
"interpolatingmodes:linear|bilinear|trilinear")
else:
ifalign_cornersisNone:
warnings.warn("Defaultupsamplingbehaviorwhenmode={}ischanged"
"toalign_corners=Falsesince0.4.0.Pleasespecify"
"align_corners=Trueiftheoldbehaviorisdesired."
"Seethedocumentationofnn.Upsamplefordetails.".format(mode))
align_corners=False
ifinput.dim()==3andmode=='nearest':
returntorch._C._nn.upsample_nearest1d(input,_output_size(1))
elifinput.dim()==4andmode=='nearest':
returntorch._C._nn.upsample_nearest2d(input,_output_size(2))
elifinput.dim()==5andmode=='nearest':
returntorch._C._nn.upsample_nearest3d(input,_output_size(3))
elifinput.dim()==3andmode=='area':
returnadaptive_avg_pool1d(input,_output_size(1))
elifinput.dim()==4andmode=='area':
returnadaptive_avg_pool2d(input,_output_size(2))
elifinput.dim()==5andmode=='area':
returnadaptive_avg_pool3d(input,_output_size(3))
elifinput.dim()==3andmode=='linear':
returntorch._C._nn.upsample_linear1d(input,_output_size(1),align_corners)
elifinput.dim()==3andmode=='bilinear':
raiseNotImplementedError("Got3Dinput,butbilinearmodeneeds4Dinput")
elifinput.dim()==3andmode=='trilinear':
raiseNotImplementedError("Got3Dinput,buttrilinearmodeneeds5Dinput")
elifinput.dim()==4andmode=='linear':
raiseNotImplementedError("Got4Dinput,butlinearmodeneeds3Dinput")
elifinput.dim()==4andmode=='bilinear':
returntorch._C._nn.upsample_bilinear2d(input,_output_size(2),align_corners)
elifinput.dim()==4andmode=='trilinear':
raiseNotImplementedError("Got4Dinput,buttrilinearmodeneeds5Dinput")
elifinput.dim()==5andmode=='linear':
raiseNotImplementedError("Got5Dinput,butlinearmodeneeds3Dinput")
elifinput.dim()==5andmode=='bilinear':
raiseNotImplementedError("Got5Dinput,butbilinearmodeneeds4Dinput")
elifinput.dim()==5andmode=='trilinear':
returntorch._C._nn.upsample_trilinear3d(input,_output_size(3),align_corners)
else:
raiseNotImplementedError("InputError:Only3D,4Dand5DinputTensorssupported"
"(got{}D)forthemodes:nearest|linear|bilinear|trilinear"
"(got{})".format(input.dim(),mode))
举个例子:
x=Variable(torch.randn([1,3,64,64])) y0=F.interpolate(x,scale_factor=0.5) y1=F.interpolate(x,size=[32,32]) y2=F.interpolate(x,size=[128,128],mode="bilinear") print(y0.shape) print(y1.shape) print(y2.shape)
这里注意上采样的时候mode默认是“nearest”,这里指定双线性插值“bilinear”
得到结果
torch.Size([1,3,32,32]) torch.Size([1,3,32,32]) torch.Size([1,3,128,128])
补充知识:pytorch插值函数interpolate——图像上采样-下采样,scipy插值函数zoom
在训练过程中,需要对图像数据进行插值,如果此时数据是numpy数据,那么可以使用scipy中的zoom函数:
fromscipy.ndimage.interpolationimportzoom
defzoom(input,zoom,output=None,order=3,mode='constant',cval=0.0,
prefilter=True):
"""
Zoomanarray.
Thearrayiszoomedusingsplineinterpolationoftherequestedorder.
Parameters
----------
%(input)s
zoom:floatorsequence
Thezoomfactoralongtheaxes.Ifafloat,`zoom`isthesameforeach
axis.Ifasequence,`zoom`shouldcontainonevalueforeachaxis.
%(output)s
order:int,optional
Theorderofthesplineinterpolation,defaultis3.
Theorderhastobeintherange0-5.
%(mode)s
%(cval)s
%(prefilter)s
Returns
-------
zoom:ndarray
Thezoomedinput.
Examples
--------
>>>fromscipyimportndimage,misc
>>>importmatplotlib.pyplotasplt
>>>fig=plt.figure()
>>>ax1=fig.add_subplot(121)#leftside
>>>ax2=fig.add_subplot(122)#rightside
>>>ascent=misc.ascent()
>>>result=ndimage.zoom(ascent,3.0)
>>>ax1.imshow(ascent)
>>>ax2.imshow(result)
>>>plt.show()
>>>print(ascent.shape)
(512,512)
>>>print(result.shape)
(1536,1536)
"""
iforder<0ororder>5:
raiseRuntimeError('splineordernotsupported')
input=numpy.asarray(input)
ifnumpy.iscomplexobj(input):
raiseTypeError('Complextypenotsupported')
ifinput.ndim<1:
raiseRuntimeError('inputandoutputrankmustbe>0')
mode=_ni_support._extend_mode_to_code(mode)
ifprefilterandorder>1:
filtered=spline_filter(input,order,output=numpy.float64)
else:
filtered=input
zoom=_ni_support._normalize_sequence(zoom,input.ndim)
output_shape=tuple(
[int(round(ii*jj))forii,jjinzip(input.shape,zoom)])
output_shape_old=tuple(
[int(ii*jj)forii,jjinzip(input.shape,zoom)])
ifoutput_shape!=output_shape_old:
warnings.warn(
"Fromscipy0.13.0,theoutputshapeofzoom()iscalculated"
"withround()insteadofint()-fortheseinputsthesizeof"
"thereturnedarrayhaschanged.",UserWarning)
zoom_div=numpy.array(output_shape,float)-1
#Zoomingtoinfinitevaluesisunpredictable,sojustchoose
#zoomfactor1instead
zoom=numpy.divide(numpy.array(input.shape)-1,zoom_div,
out=numpy.ones_like(input.shape,dtype=numpy.float64),
where=zoom_div!=0)
output=_ni_support._get_output(output,input,
shape=output_shape)
zoom=numpy.ascontiguousarray(zoom)
_nd_image.zoom_shift(filtered,zoom,None,output,order,mode,cval)
returnoutput
中的zoom函数进行插值,
但是,如果此时的数据是tensor(张量)的时候,使用zoom函数的时候需要将tensor数据转为numpy,将GPU数据转换为CPU数据等,过程比较繁琐,可以使用pytorch自带的函数进行插值操作,interpolate函数有几个参数:size表示输出大小,scale_factor表示缩放倍数,mode表示插值方式,align_corners是bool类型,表示输入和输出中心是否对齐:
fromtorch.nn.functionalimportinterpolate
definterpolate(input,size=None,scale_factor=None,mode='nearest',align_corners=None):
r"""Down/upsamplestheinputtoeitherthegiven:attr:`size`orthegiven
:attr:`scale_factor`
Thealgorithmusedforinterpolationisdeterminedby:attr:`mode`.
Currentlytemporal,spatialandvolumetricsamplingaresupported,i.e.
expectedinputsare3-D,4-Dor5-Dinshape.
Theinputdimensionsareinterpretedintheform:
`mini-batchxchannelsx[optionaldepth]x[optionalheight]xwidth`.
Themodesavailableforresizingare:`nearest`,`linear`(3D-only),
`bilinear`,`bicubic`(4D-only),`trilinear`(5D-only),`area`
Args:
input(Tensor):theinputtensor
size(intorTuple[int]orTuple[int,int]orTuple[int,int,int]):
outputspatialsize.
scale_factor(floatorTuple[float]):multiplierforspatialsize.Hastomatchinputsizeifitisatuple.
mode(str):algorithmusedforupsampling:
``'nearest'``|``'linear'``|``'bilinear'``|``'bicubic'``|
``'trilinear'``|``'area'``.Default:``'nearest'``
align_corners(bool,optional):Geometrically,weconsiderthepixelsofthe
inputandoutputassquaresratherthanpoints.
Ifsetto``True``,theinputandoutputtensorsarealignedbythe
centerpointsoftheircornerpixels.Ifsetto``False``,theinputand
outputtensorsarealignedbythecornerpointsoftheircorner
pixels,andtheinterpolationusesedgevaluepaddingforout-of-boundaryvalues.
Thisonlyhaseffectwhen:attr:`mode`is``'linear'``,
``'bilinear'``,``'bicubic'``,or``'trilinear'``.
Default:``False``
..warning::
With``align_corners=True``,thelinearlyinterpolatingmodes
(`linear`,`bilinear`,and`trilinear`)don'tproportionallyalignthe
outputandinputpixels,andthustheoutputvaluescandependonthe
inputsize.Thiswasthedefaultbehaviorforthesemodesuptoversion
0.3.1.Sincethen,thedefaultbehavioris``align_corners=False``.
See:class:`~torch.nn.Upsample`forconcreteexamplesonhowthis
affectstheoutputs.
..include::cuda_deterministic_backward.rst
"""
from.modules.utilsimport_ntuple
def_check_size_scale_factor(dim):
ifsizeisNoneandscale_factorisNone:
raiseValueError('eithersizeorscale_factorshouldbedefined')
ifsizeisnotNoneandscale_factorisnotNone:
raiseValueError('onlyoneofsizeorscale_factorshouldbedefined')
ifscale_factorisnotNoneandisinstance(scale_factor,tuple)\
andlen(scale_factor)!=dim:
raiseValueError('scale_factorshapemustmatchinputshape.'
'Inputis{}D,scale_factorsizeis{}'.format(dim,len(scale_factor)))
def_output_size(dim):
_check_size_scale_factor(dim)
ifsizeisnotNone:
returnsize
scale_factors=_ntuple(dim)(scale_factor)
#math.floormightreturnfloatinpy2.7
#makescale_factoratensorintracingsoconstantdoesn'tgetbakedin
iftorch._C._get_tracing_state():
return[(torch.floor(input.size(i+2)*torch.tensor(float(scale_factors[i]))))foriinrange(dim)]
else:
return[int(math.floor(int(input.size(i+2))*scale_factors[i]))foriinrange(dim)]
ifmodein('nearest','area'):
ifalign_cornersisnotNone:
raiseValueError("align_cornersoptioncanonlybesetwiththe"
"interpolatingmodes:linear|bilinear|bicubic|trilinear")
else:
ifalign_cornersisNone:
warnings.warn("Defaultupsamplingbehaviorwhenmode={}ischanged"
"toalign_corners=Falsesince0.4.0.Pleasespecify"
"align_corners=Trueiftheoldbehaviorisdesired."
"Seethedocumentationofnn.Upsamplefordetails.".format(mode))
align_corners=False
ifinput.dim()==3andmode=='nearest':
returntorch._C._nn.upsample_nearest1d(input,_output_size(1))
elifinput.dim()==4andmode=='nearest':
returntorch._C._nn.upsample_nearest2d(input,_output_size(2))
elifinput.dim()==5andmode=='nearest':
returntorch._C._nn.upsample_nearest3d(input,_output_size(3))
elifinput.dim()==3andmode=='area':
returnadaptive_avg_pool1d(input,_output_size(1))
elifinput.dim()==4andmode=='area':
returnadaptive_avg_pool2d(input,_output_size(2))
elifinput.dim()==5andmode=='area':
returnadaptive_avg_pool3d(input,_output_size(3))
elifinput.dim()==3andmode=='linear':
returntorch._C._nn.upsample_linear1d(input,_output_size(1),align_corners)
elifinput.dim()==3andmode=='bilinear':
raiseNotImplementedError("Got3Dinput,butbilinearmodeneeds4Dinput")
elifinput.dim()==3andmode=='trilinear':
raiseNotImplementedError("Got3Dinput,buttrilinearmodeneeds5Dinput")
elifinput.dim()==4andmode=='linear':
raiseNotImplementedError("Got4Dinput,butlinearmodeneeds3Dinput")
elifinput.dim()==4andmode=='bilinear':
returntorch._C._nn.upsample_bilinear2d(input,_output_size(2),align_corners)
elifinput.dim()==4andmode=='trilinear':
raiseNotImplementedError("Got4Dinput,buttrilinearmodeneeds5Dinput")
elifinput.dim()==5andmode=='linear':
raiseNotImplementedError("Got5Dinput,butlinearmodeneeds3Dinput")
elifinput.dim()==5andmode=='bilinear':
raiseNotImplementedError("Got5Dinput,butbilinearmodeneeds4Dinput")
elifinput.dim()==5andmode=='trilinear':
returntorch._C._nn.upsample_trilinear3d(input,_output_size(3),align_corners)
elifinput.dim()==4andmode=='bicubic':
returntorch._C._nn.upsample_bicubic2d(input,_output_size(2),align_corners)
else:
raiseNotImplementedError("InputError:Only3D,4Dand5DinputTensorssupported"
"(got{}D)forthemodes:nearest|linear|bilinear|bicubic|trilinear"
"(got{})".format(input.dim(),mode))
以上这篇Pytorch上下采样函数--interpolate用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。