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用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。