o % i?m@sddlmZddlZddlmZddlmZddlZddlm m Z ddlm Z ddl m Z ddlmZddlmZdd lmZdd lmZmZmZmZmZmZmZed \ZZed \ZZgd ZGddde j Z!Gddde j Z"Gddde j Z#Gddde j Z$dOd#d$Z%dPdQd(d)Z&dRd+d,Z'Gd-d.d.e j Z(Gd/d0d0e j Z)ej*dfdSd3d4Z+ 5 6 dTdUd;d<Z,Gd=d>d>e j Z-Gd?d@d@e j Z.GdAdBdBe Z/GdCdDdDe j Z0GdEdFdFe j Z1GdGdHdHe1Z2GdIdJdJe1Z3GdKdLdLe1Z4GdMdNdNe4Z5dS)V) annotationsNdeepcopy)Sequence)nn)Function)NdarrayOrTensor) gaussian_1d)Conv)ChannelMatchingSkipModeconvert_to_tensorensure_tuple_repissequenceiterablelook_up_optionoptional_importzmonai._Cz torch.fft) ChannelPadFlattenGaussianFilterHilbertTransformLLTM MedianFilterReshapeSavitzkyGolayFilterSkipConnection apply_filter median_filterseparable_filteringcs2eZdZdZejfdfdd Zdd dZZS)rz Expand the input tensor's channel dimension from length `in_channels` to `out_channels`, by padding or a projection. spatial_dimsint in_channels out_channelsmodeChannelMatching | strc std|_d|_||krdSt|t}|tjkr,ttj|f}|||dd|_dS|tj krZ||kr9t d||d}|||}ddg|||gddg}t ||_dSdS)a Args: spatial_dims: number of spatial dimensions of the input image. in_channels: number of input channels. out_channels: number of output channels. mode: {``"pad"``, ``"project"``} Specifies handling residual branch and conv branch channel mismatches. Defaults to ``"pad"``. - ``"pad"``: with zero padding. - ``"project"``: with a trainable conv with kernel size one. N) kernel_sizezKIncompatible values: channel_matching="pad" and in_channels > out_channels.r) super__init__projectpadrr PROJECTr CONVPAD ValueErrortuple) selfrr r!r" conv_typeZpad_1Zpad_2r* __class__d/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/networks/layers/simplelayers.pyr(=s&       zChannelPad.__init__x torch.TensorreturncCs6|jdur t||S|jdurt||jS|SN)r)torch as_tensorr*Fr0r6r4r4r5forward_s  zChannelPad.forward)rrr rr!rr"r#r6r7r8r7) __name__ __module__ __qualname____doc__r r-r(r> __classcell__r4r4r2r5r7s "rc.eZdZdZddfd d ZdddZZS)rz Combine the forward pass input with the result from the given submodule:: --+--submodule--o-- |_____________| The available modes are ``"cat"``, ``"add"``, ``"mul"``. r$catdimrr"str | SkipModer8Nonecs(t||_||_t|tj|_dS)a Args: submodule: the module defines the trainable branch. dim: the dimension over which the tensors are concatenated. Used when mode is ``"cat"``. mode: ``"cat"``, ``"add"``, ``"mul"``. defaults to ``"cat"``. N)r'r( submodulerGrr valuer")r0rJrGr"r2r4r5r(qs zSkipConnection.__init__r6r7cCsf||}|jdkrtj||g|jdS|jdkrt||S|jdkr*t||Std|jd)NrFrGaddmulzUnsupported mode .)rJr"r:rFrGrMrNNotImplementedError)r0r6yr4r4r5r>s      zSkipConnection.forward)r$rF)rGrr"rHr8rIr?r@rArBrCr(r>rDr4r4r2r5rgs rc@seZdZdZdddZdS) rzM Flattens the given input in the forward pass to be [B,-1] in shape. r6r7r8cCs||ddS)Nr)viewsizer=r4r4r5r>szFlatten.forwardNr?)r@rArBrCr>r4r4r4r5rsrc,eZdZdZd fdd Zd d d ZZS)rzk Reshapes input tensors to the given shape (minus batch dimension), retaining original batch size. shaperr8rIcstdt||_dS)a Given a shape list/tuple `shape` of integers (s0, s1, ... , sn), this layer will reshape input tensors of shape (batch, s0 * s1 * ... * sn) to shape (batch, s0, s1, ... , sn). Args: shape: list/tuple of integer shape dimensions r$N)r'r(r/rW)r0rWr2r4r5r(s zReshape.__init__r6r7cCs"t|j}|jd|d<||S)Nr)listrWreshape)r0r6rWr4r4r5r>s  zReshape.forward)rWrr8rIr?rRr4r4r2r5rs rinput_r7kernelslist[torch.Tensor]pad_modestrdrrpaddings list[int] num_channelsr8c Cs|dkr|Sdgt|j}d||d<|||}|dkr3|ddkr3t||||d|||S||dgdg|}dg|} ||| |<tjtjtj g|d} ddt | D} t | g} tj || |d} | t| |||d|||||dS) Nrr$rSr&cSsg|]}||gqSr4r4).0pr4r4r5 z-_separable_filtering_conv..r")inputweightgroups) lenrWrZnumel_separable_filtering_convrepeatr<conv1dconv2dconv3dreversedsumr*)r[r\r^r`rrarcs_kernel_paddingr1 _reversed_padding_repeated_twiceZ$_sum_reversed_padding_repeated_twice padded_inputr4r4r5rns&     rnzerosr6r"csttjstdtjdtjd}t|tjr#|g|}fdd|D}dd|D}jd}|dkr>d n|}t|||d|||S) a1 Apply 1-D convolutions along each spatial dimension of `x`. Args: x: the input image. must have shape (batch, channels, H[, W, ...]). kernels: kernel along each spatial dimension. could be a single kernel (duplicated for all spatial dimensions), or a list of `spatial_dims` number of kernels. mode (string, optional): padding mode passed to convolution class. ``'zeros'``, ``'reflect'``, ``'replicate'`` or ``'circular'``. Default: ``'zeros'``. See ``torch.nn.Conv1d()`` for more information. Raises: TypeError: When ``x`` is not a ``torch.Tensor``. Examples: .. code-block:: python >>> import torch >>> from monai.networks.layers import separable_filtering >>> img = torch.randn(2, 4, 32, 32) # batch_size 2, channels 4, 32x32 2D images # applying a [-1, 0, 1] filter along each of the spatial dimensions. # the output shape is the same as the input shape. >>> out = separable_filtering(img, torch.tensor((-1., 0., 1.))) # applying `[-1, 0, 1]`, `[1, 0, -1]` filters along two spatial dimensions respectively. # the output shape is the same as the input shape. >>> out = separable_filtering(img, [torch.tensor((-1., 0., 1.)), torch.tensor((1., 0., -1.))]) x must be a torch.Tensor but is rOr&csg|]}|qSr4)tordrur6r4r5rfsz'separable_filtering..cSsg|] }|jdddqS)rr$r&)rW)rdkr4r4r5rfr$rzconstant) isinstancer:Tensor TypeErrortyper@rlrWrn)r6r\r"r_kernelsZ _paddingsZn_chsr^r4r~r5rs    rkernelc Ksft|tjstdt|jd|j^}}}t|}|dkr'td|dt|j}||ks6||dkrGt d|d|dd|jd| |}|j ||g|j||d R}|j d d g|jdd R}|j d |jd g|R}tjtjtjg|d }d |vrd|d <d|vrd |d<|||f|jd d d|} | j ||g| jdd RS)a Filtering `x` with `kernel` independently for each batch and channel respectively. Args: x: the input image, must have shape (batch, channels, H[, W, D]). kernel: `kernel` must at least have the spatial shape (H_k[, W_k, D_k]). `kernel` shape must be broadcastable to the `batch` and `channels` dimensions of `x`. kwargs: keyword arguments passed to `conv*d()` functions. Returns: The filtered `x`. Examples: .. code-block:: python >>> import torch >>> from monai.networks.layers import apply_filter >>> img = torch.rand(2, 5, 10, 10) # batch_size 2, channels 5, 10x10 2D images >>> out = apply_filter(img, torch.rand(3, 3)) # spatial kernel >>> out = apply_filter(img, torch.rand(5, 3, 3)) # channel-wise kernels >>> out = apply_filter(img, torch.rand(2, 5, 3, 3)) # batch-, channel-wise kernels r{rOz6Only spatial dimensions up to 3 are supported but got r&zkernel must have z ~ z% dimensions to match the input shape NrSr$rpaddingsamestride)rkbias)rr:rrrr@rWrlrPr.r|expandrZrTr<rprqrr) r6rkwargsbatchZchnsZspatialsZ n_spatialZk_sizeconvoutputr4r4r5rs,    "rcs:eZdZdZddfd d ZdddZeddZZS)raR Convolve a Tensor along a particular axis with a Savitzky-Golay kernel. Args: window_length: Length of the filter window, must be a positive odd integer. order: Order of the polynomial to fit to each window, must be less than ``window_length``. axis (optional): Axis along which to apply the filter kernel. Default 2 (first spatial dimension). mode (string, optional): padding mode passed to convolution class. ``'zeros'``, ``'reflect'``, ``'replicate'`` or ``'circular'``. Default: ``'zeros'``. See torch.nn.Conv1d() for more information. r&rz window_lengthrorderaxisr"r_cs8t||kr td||_||_||||_dS)Nz&order must be less than window_length.)r'r(r.rr" _make_coeffscoeffs)r0rrrr"r2r4r5r(;s zSavitzkyGolayFilter.__init__r6r7r8c Cstj|t|tjr |jndd}t|rtd|jtjd}|j dks/|j t |j dkrDs     zSavitzkyGolayFilter.forwardcCst|d\}}|dkrtdtj||d| ddtjdd}|tj|dtjdddd}tj|dtjdd}d|d<tj||j S) Nr&rzwindow_length must be odd.r$rScpurr?) divmodr.r:arangerrZrzlinalglstsqsolutionsqueeze)rrZ half_lengthremidxarQr4r4r5res$"z SavitzkyGolayFilter._make_coeffs)r&rz)rrrrrrr"r_r?) r@rArBrCr(r> staticmethodrrDr4r4r2r5r/s  !rcrE)ra Determine the analytical signal of a Tensor along a particular axis. Args: axis: Axis along which to apply Hilbert transform. Default 2 (first spatial dimension). n: Number of Fourier components (i.e. FFT size). Default: ``x.shape[axis]``. r&Nrrn int | Noner8rIcst||_||_dSr9)r'r(rr)r0rrr2r4r5r({s  zHilbertTransform.__init__r6r7c Cstj|t|tjr |jndd}t|rtd|jtjd}|j dks/|j t |j dkrs4 ("    zHilbertTransform.forward)r&N)rrrrr8rIr?rRr4r4r2r5rrsr window_size Sequence[int]cCs@t|tdd}t|}|dg|}ttj|||d|S)zv Create a binary kernel to extract the patches. The window size HxWxD will create a (H*W*D)xHxWxD kernel. T wrap_sequencer$r)r rr:proddiagrrT)rrrwin_sizerrur4r4r5get_binary_kernels  rrrrr in_tensorr%Sequence[int] | inttorch.Tensor | NonecKs.t|tjstdt||j}|dt|||| d}}tt|t dd}|dur@t ||}t ||j |j }n||}tjtjtjg|d} |j|dg|R} ddt|jddD} tj| | d d } | | |fd dd |} | j|d g|R} tj| ddd }||}|S)a Apply median filter to an image. Args: in_tensor: input tensor; median filtering will be applied to the last `spatial_dims` dimensions. kernel_size: the convolution kernel size. spatial_dims: number of spatial dimensions to apply median filtering. kernel: an optional customized kernel. kwargs: additional parameters to the `conv`. Returns: the filtered input tensor, shape remains the same as ``in_tensor`` Example:: >>> from monai.networks.layers import median_filter >>> import torch >>> x = torch.rand(4, 5, 7, 6) >>> output = median_filter(x, (3, 3, 3)) >>> output.shape torch.Size([4, 5, 7, 6]) z&Input type is not a torch.Tensor. Got NTrr$cSs&g|]}tdD]}|ddqqS)r&r$)r)rdrrr4r4r5rfs&z!median_filter..r& replicate)r*r"r)rrrSrL)rr:rrrrWrlrr rrrrrr|r<rprqrrrZrsr*rTmedian)rr%rrroriginal_shapeZoshapeZsshapeZoprodrZreshaped_inputrryfeaturesrr4r4r5rs$ $   rcs0eZdZdZddfd d ZddddZZS)ra Apply median filter to an image. Args: radius: the blurring kernel radius (radius of 1 corresponds to 3x3x3 kernel when spatial_dims=3). Returns: filtered input tensor. Example:: >>> from monai.networks.layers import MedianFilter >>> import torch >>> in_tensor = torch.rand(4, 5, 7, 6) >>> blur = MedianFilter([1, 1, 1]) # 3x3x3 kernel >>> output = blur(in_tensor) >>> output.shape torch.Size([4, 5, 7, 6]) rrradiusrrrr8rIcsBt||_t|||_dd|jD|_t|j|d|_dS)NcSsg|] }ddt|qS)r$r&r)rdrr4r4r5rfsz)MedianFilter.__init__..r)r'r(rrrwindowrr)r0rrrr2r4r5r( s  zMedianFilter.__init__r$rr7cCs(|}t|D] }t||j|jd}q|S)z Args: in_tensor: input tensor, median filtering will be applied to the last `spatial_dims` dimensions. number_of_passes: median filtering will be repeated this many times )rr)rrrr)r0rZnumber_of_passesr6rr4r4r5r>s zMedianFilter.forward)rr)rrrrr8rIrX)rr7r8r7rRr4r4r2r5rsrcs0eZdZ   ddfdd ZdddZZS)r@erfFrrsigma?Sequence[float] | float | Sequence[torch.Tensor] | torch.Tensor truncatedrapproxr_ requires_gradboolr8rIcstr t|kr tn fddt|DtfddD|_||_||_t |jD] \}}| d||q2dS)a> Args: spatial_dims: number of spatial dimensions of the input image. must have shape (Batch, channels, H[, W, ...]). sigma: std. could be a single value, or `spatial_dims` number of values. truncated: spreads how many stds. approx: discrete Gaussian kernel type, available options are "erf", "sampled", and "scalespace". - ``erf`` approximation interpolates the error function; - ``sampled`` uses a sampled Gaussian kernel; - ``scalespace`` corresponds to https://en.wikipedia.org/wiki/Scale_space_implementation#The_discrete_Gaussian_kernel based on the modified Bessel functions. requires_grad: whether to store the gradients for sigma. if True, `sigma` will be the initial value of the parameters of this module (for example `parameters()` iterator could be used to get the parameters); otherwise this module will fix the kernels using `sigma` as the std. csg|]}tqSr4rrdr)rr4r5rf?rgz+GaussianFilter.__init__..c s<g|]}tjjtj|tjt|tjr|jndddqS)Nrr)r:r Parameterr;rrrrr}rr4r5rfAs"Z kernel_sigma_N) rrlr.rr'r(rrr enumerateregister_parameter)r0rrrrrrparamr2)rrr5r( s   zGaussianFilter.__init__r6r7cs fddjD}t||dS)zG Args: x: in shape [Batch, chns, H, W, D]. csg|] }t|jjdqS))rr)r rrr}r0r4r5rfRrz*GaussianFilter.forward..)r6r\)rr)r0r6rvr4rr5r>Ms zGaussianFilter.forward)rrF) rrrrrrrr_rrr8rIr?)r@rArBr(r>rDr4r4r2r5rs -rc@s$eZdZeddZeddZdS) LLTMFunctionc CsFt|||||}|dd\}}|dd|g} |j| ||fS)Nr&r$)_CZ lltm_forwardsave_for_backward) ctxriweightsrZold_hZold_celloutputsZnew_hZnew_cell variablesr4r4r5r>Xs  zLLTMFunction.forwardc CsBtj||g|jR}|dd\}}}}}|||||fS)N)rZ lltm_backward contiguous saved_tensors) rZgrad_hZ grad_cellrZd_old_hd_inputZ d_weightsd_biasZ d_old_cellr4r4r5backwardaszLLTMFunction.backwardN)r@rArBrr>rr4r4r4r5rVs  rcs2eZdZdZd fdd ZddZd d ZZS) raF This recurrent unit is similar to an LSTM, but differs in that it lacks a forget gate and uses an Exponential Linear Unit (ELU) as its internal activation function. Because this unit never forgets, call it LLTM, or Long-Long-Term-Memory unit. It has both C++ and CUDA implementation, automatically switch according to the target device where put this module to. Args: input_features: size of input feature data state_size: size of the state of recurrent unit Referring to: https://pytorch.org/tutorials/advanced/cpp_extension.html input_featuresr state_sizecsVt||_||_ttd||||_ttdd||_ | dS)Nrr$) r'r(rrrrr:emptyrrreset_parameters)r0rrr2r4r5r(xs  z LLTM.__init__cCs4dt|j}|D] }|j| | q dS)Nr)mathsqrtr parametersdatauniform_)r0stdvrjr4r4r5rs zLLTM.reset_parameterscCstj||j|jg|RSr9)rapplyrr)r0ristater4r4r5r>sz LLTM.forward)rrrr)r@rArBrCr(rr>rDr4r4r2r5ris rcrV) ApplyFilterz,Wrapper class to apply a filter to an image.filterrr8rIcstt|tjd|_dS)Nr)r'r(r r:float32r)r0rr2r4r5r(s zApplyFilter.__init__r6r7cCs t||jSr9)rrr=r4r4r5r>s zApplyFilter.forward)rrr8rIr?rRr4r4r2r5rsrc"eZdZdZd fdd ZZS) MeanFilterz Mean filtering can smooth edges and remove aliasing artifacts in an segmentation image. The mean filter used, is a `torch.Tensor` of all ones. rrrUr8rIcs&t|g|}|}tj|ddS) Args: spatial_dims: `int` of either 2 for 2D images and 3 for 3D images size: edge length of the filter rN)r:rr'r()r0rrUrr2r4r5r(szMeanFilter.__init__rrrUrr8rIr@rArBrCr(rDr4r4r2r5rrcr) LaplaceFilterz Laplacian filtering for outline detection in images. Can be used to transform labels to contours. The laplace filter used, is a `torch.Tensor` where all values are -1, except the center value which is `size` ** `spatial_dims` rrrUr8rIcsLt|g|d}t|dg|}||d||<tj|ddS)rr$r&rN)r:rzrr/r'r()r0rrUr center_pointr2r4r5r(szLaplaceFilter.__init__rrr4r4r2r5rrcr) EllipticalFilterz Elliptical filter, can be used to dilate labels or label-contours. The elliptical filter used here, is a `torch.Tensor` with shape (size, ) * ndim containing a circle/sphere of `1` rrrUr8rIcsbdtjfddt|D}tfdd|Ddd}|dk}tj|ddS)rr&csg|]}tdqS)r)r:rr)rUr4r5rfz-EllipticalFilter.__init__..csg|]}|dqS)r&r4)rdr)rr4r5rfr rrN)r:meshgridrstackrtr'r()r0rrUgridZsquared_distancesrr2)rrUr5r(s   zEllipticalFilter.__init__rrr4r4r2r5r rr cr) SharpenFilterz Convolutional filter to sharpen a 2D or 3D image. The filter used contains a circle/sphere of `-1`, with the center value being the absolute sum of all non-zero elements in the kernel rrrUr8rIcsHtj||dt|dg|}|j}|jd9_||j|<dS)r)rrUr&rSN)r'r(r/rrt)r0rrUrZ center_valuer2r4r5r(s  zSharpenFilter.__init__rrr4r4r2r5rr r)r[r7r\r]r^r_r`rrrrarbrcrr8r7)rz)r6r7r\r]r"r_r8r7)r6r7rr7r8r7)rrr8r7)rrN) rr7r%rrrrrr8r7)6 __future__rrcopyrtypingrr:torch.nn.functionalr functionalr<Ztorch.autogradrmonai.config.type_definitionsrZmonai.networks.layers.convutilsr Zmonai.networks.layers.factoriesr monai.utilsr r r rrrrrrr__all__Modulerrrrrnrrrrrrrrrrrrrrr rr4r4r4r5sL        $ 0$  % -3C<  <)8