在Python中使用InputSpec()函数实现输入规范化
在Python中使用InputSpec()函数可以实现输入规范化,保证输入数据的格式和类型符合预期。下面是一个使用InputSpec()函数的示例代码:
`python
from typing import Union
from haolib.cmds import cst
from haolib import *
from torch.nn import functional as F
from typing import Union
from torchvision.models.inception import InceptionOutputs, Inception3
from torch.autograd import Variable
from torchvision.models.inception import inception_v3
from torch import jit
from torch import nn
from torch.utils import model_zoo
from torchvision import transforms
from real_nvp_model import RealNVP
from typing import Callable
from tqdm import tqdm
from torch.utils.data import DataLoader
import torch.utils.data as data
from torch.nn.functional import softplus
from torch.nn import Parameter
from torch.nn import Module
import os
import torch
import pandas as pd
from collections import OrderedDict
def _triple_same_pad(in_dim, out_dim, kernel_size, dilation):
p = ((out_dim[0] - 1) * dilation[0] + kernel_size[0] + in_dim[0] - out_dim[0]) // 2
q = ((out_dim[1] - 1) * dilation[1] + kernel_size[1] + in_dim[1] - out_dim[1]) // 2
r = ((out_dim[2] - 1) * dilation[2] + kernel_size[2] + in_dim[2] - out_dim[2]) // 2
return [p, q, r]
def uniform_binning_correction(y, n_bits):
"""Replaces the piecewise linear function s: R -> R^3 used in uniform_binning T with its inverse.
Args:
y: 3D Tensor.
n_bits: Number of bits.
Returns:
Adjusted / corrected y.
"""
if n_bits == 0:
return y
assert n_bits >= 1
max_value = 2. ** n_bits - 1
# Constants.
EPSILON = torch.cuda.FloatTensor([1e-6])
ONE_HALF = torch.cuda.FloatTensor([0.5])
# Add noise.
y = y + torch.cuda.FloatTensor(y.size()).uniform_(EPSILON[0], 1. - EPSILON[0])
# Transform to interval ]0, 1[.
y = y / (max_value + ONE_HALF)
# Inverse 3D Tensor.
y = atanh((2 * y - 1).clamp(-1 + EPSILON[0], 1 - EPSILON[0])) / (2 * max_value)
return y
class coupling(nn.Module):
def __init__(self, x_size, h_size, rescale=1.):
super().__init__()
self.rescale = rescale
self.WN = nn.Sequential(OrderedDict([
('norm_1', actnorm(x_size)),
('conv_1x1', nn.Conv3d(in_channels=x_size[0], out_channels=h_size, kernel_size=1, bias=True)),
('relu_1', nn.ReLU(inplace=True)),
('norm_2', actnorm(h_size)),
('conv_3x3', nn.Conv3d(in_channels=h_size, out_channels=h_size, kernel_size=3, padding=1, bias=True)),
('relu_2', nn.ReLU(inplace=True)),
('norm_3', actnorm(h_size)),
('conv_1x1_out', nn.Conv3d(in_channels=h_size, out_channels=2 * x_size[0], kernel_size=1, bias=True)),
]))
def forward(self, x, ldj, reverse=False):
if reverse:
return self.reverse(x, ldj)
else:
return self.normal_flow(x, ldj)
def normal_flow(self, x, ldj):
z, z_shift = split_feature(x)
h = self.WN(z)
shift, scale = split_feature(h)
scale = self.rescale * torch.tanh(scale)
shift = self.rescale * scale * shift
x = z_shift + (z * torch.exp(scale) + shift)
ldj += compute_log_det_jacobian(scale, x)
return x, ldj
def reverse(self, x, ldj):
z, z_shift = split_feature(x)
h = self.WN(z)
shift, scale = split_feature(h)
scale = self.rescale * torch.tanh(scale)
shift = self.rescale * scale * shift
inv_scale = torch.exp(-scale)
inv_shift = -shift * inv_scale
x = (z - z_shift - inv_shift) * inv_scale
ldj -= compute_log_det_jacobian(scale, x)
return x, ldj
class realnvp(nn.Module):
def __init__(self, x_size, h_size, n_flows):
super().__init__()
self.net = coupling(x_size, h_size)
self.flows = nn.ModuleList([self.net for _ in range(n_flows)])
def forward(self, x, ldj, reverse=False):
if reverse:
return self.reverse(x, ldj)
else:
return self.normal_flow(x, ldj)
def normal_flow(self, x, ldj):
for flow in self.flows:
x, ldj = flow(x, ldj)
return x, ldj
def reverse(self, x, ldj):
for flow in self.flows[::-1]:
x, ldj = flow(x, ldj, reverse=True)
return x, ldj
class RealNVP(RealNVP):
def advise(self):
print('It helpful to have one group that is defined completely.
Example:')
print('?Example_augments')
print('OneA({}),
TwoV({}),
ThreeH({}),
ThreeH({}),
TwoV({}),
ThreeH({}),
ThreeH({})'.format(').affine(]')
for _ in range(self.max_group_size - 2):
print(',')
print('
?Label_Grade')
print('Aindex TokenNameIdentifierà),
Bindex.rx(]),\approximately]).affine(],
[ approximately ], approximately }).affine(]')
class Wrapper(RealNVP):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__name__ = "realnvp_dct"
def forward(self, x, reverse=False): # noqa: F811
return super().forward(x, c=self.c)
def initialize_weights(w):
classname = w.__class__.__name__
if classname.find('Conv') != -1:
nn.init.orthogonal_(w.weight.data)
if w.bias is not None:
w.bias.data.fill_(0)
elif classname.find('BatchNorm3d') != -1:
w.weight.data.normal_(0.0, 0.02)
w.bias.data.fill_(0)
class actnorm(nn.Module):
def __init__(self, x_size, logscale_factor=3.):
super().__init__()
self.logscale_factor = logscale_factor
self.scale = nn.Parameter(torch.ones(1, x_size[0], 1, 1, 1) * 3.0)
self.bias = nn.Parameter(torch.zeros(1, x_size[0], 1, 1, 1))
def forward(self, x, reverse=False):
if reverse:
return self.reverse(x)
else:
return self.normal_flow(x)
def normal_flow(self, x):
d = torch.log(self.scale) * self.logscale_factor
x = x + self.bias
return x * torch.exp(d)
def reverse(self, x):
d = torch.log(self.scale) * self.logscale_factor
x = x * torch.exp(-d) - self.bias
return x
if __name__ == "__main__":
print('[INFO] Loading 3D volumes')
print('[INFO] Volumes cound is 9')
print('[INFO] Images count is 0')
path_to_csv = "Data/labels.csv"
print('[INFO] Reading ' + str(path_to_csv) + " file")
labels = pd.read_csv(path_to_csv, header=None)
labels = torch.from_numpy(labels.values).squeeze() - 1
volumes=[]
for i in range(9):
name = 'Data/npy/full_org_'+str(i)+'.npy'
print(name, "the name")
np_volume = np.float32(np.load(name))
volumes.append(np_volume)
volumes = np.array(volumes)
# Define the input shapes and types
input_spec = InputSpec()
input_spec.add_argument('volumes', shape=(9, 80, 100, 80), dtype='float32')
input_spec.add_argument('labels', shape=(9,), dtype='int64')
@input_spec(input_spec)
def train_model(volumes, labels):
# ... 训练代码 ...
# 调用带有输入规范化的函数
