""" 这是根据UNet模型搭建出的一个基本网络结构 输入和输出大小是一样的，可以根据需求进行修改 """ import torch import torch.nn as nn from torch.nn import functional as F # 基本卷积块 class Conv(nn.Module): def __init__(self, C_in, C_out): super(Conv, self).__init__() self.layer = nn.Sequential( nn.Conv2d(C_in, C_out, 3, 1, 1), nn.BatchNorm2d(C_out), # 防止过拟合 nn.Dropout(0.3), nn.LeakyReLU(), nn.Conv2d(C_out, C_out, 3, 1, 1), nn.BatchNorm2d(C_out), # 防止过拟合 nn.Dropout(0.4), nn.LeakyReLU(), ) def forward(self, x): return self.layer(x) # 下采样模块 class DownSampling(nn.Module): def __init__(self, C): super(DownSampling, self).__init__() self.Down = nn.Sequential( # 使用卷积进行2倍的下采样，通道数不变 nn.Conv2d(C, C, 3, 2, 1), nn.LeakyReLU() ) def forward(self, x): return self.Down(x) # 上采样模块 class UpSampling(nn.Module): def __init__(self, C): super(UpSampling, self).__init__() # 特征图大小扩大2倍，通道数减半 self.Up = nn.Conv2d(C, C // 2, 1, 1) def forward(self, x, r): # 使用邻近插值进行下采样 up = F.interpolate(x, scale_factor=2, mode="nearest") x = self.Up(up) # 拼接，当前上采样的，和之前下采样过程中的 return torch.cat((x, r), 1) # 主干网络 class UNet(nn.Module): def __init__(self): super(UNet, self).__init__() # 4次下采样 self.C1 = Conv(3, 64) self.D1 = DownSampling(64) self.C2 = Conv(64, 128) self.D2 = DownSampling(128) self.C3 = Conv(128, 256) self.D3 = DownSampling(256) self.C4 = Conv(256, 512) self.D4 = DownSampling(512) self.C5 = Conv(512, 1024) # 4次上采样 self.U1 = UpSampling(1024) self.C6 = Conv(1024, 512) self.U2 = UpSampling(512) self.C7 = Conv(512, 256) self.U3 = UpSampling(256) self.C8 = Conv(256, 128) self.U4 = UpSampling(128) self.C9 = Conv(128, 64) self.Th = torch.nn.Sigmoid() self.pred = torch.nn.Conv2d(64, 3, 3, 1, 1) def forward(self, x): # 下采样部分 R1 = self.C1(x) R2 = self.C2(self.D1(R1)) R3 = self.C3(self.D2(R2)) R4 = self.C4(self.D3(R3)) Y1 = self.C5(self.D4(R4)) # 上采样部分 # 上采样的时候需要拼接起来 O1 = self.C6(self.U1(Y1, R4)) O2 = self.C7(self.U2(O1, R3)) O3 = self.C8(self.U3(O2, R2)) O4 = self.C9(self.U4(O3, R1)) # 输出预测，这里大小跟输入是一致的 # 可以把下采样时的中间抠出来再进行拼接，这样修改后输出就会更小 return self.Th(self.pred(O4)) if __name__ == '__main__': a = torch.randn(2, 3, 256, 256) net = UNet() print(net(a).shape)第二个#定义UNet网络 class UNet(nn.Module): def __init__(self): super(UNet, self).__init__() self.max_pool_2x2 = nn.MaxPool2d(kernel_size=2, stride=2) self.down_conv_1 = double_conv(3, 64) self.down_conv_2 = double_conv(64, 128) self.down_conv_3 = double_conv(128, 256) self.down_conv_4 = double_conv(256, 512) self.down_conv_5 = double_conv(512, 1024) self.up_trans_1 = nn.ConvTranspose2d( in_channels=1024, out_channels=512, kernel_size=2, stride=2 ) self.up_conv_1 = double_conv(1024, 512) self.up_trans_2 = nn.ConvTranspose2d( in_channels=512, out_channels=256, kernel_size=2, stride=2 ) self.up_conv_2 = double_conv(512, 256) self.up_trans_3 = nn.ConvTranspose2d( in_channels=256, out_channels=128, kernel_size=2, stride=2 ) self.up_conv_3 = double_conv(256, 128) self.up_trans_4 = nn.ConvTranspose2d( in_channels=128, out_channels=64, kernel_size=2, stride=2 ) self.up_conv_4 = double_conv(128, 64) self.out = nn.Conv2d( in_channels=64, out_channels=1, kernel_size=1 ) def forward(self, image): # expected size # encoder (Normal convolutions decrease the size) x1 = self.down_conv_1(image) # print("x1 "+str(x1.shape)) x2 = self.max_pool_2x2(x1) # print("x2 "+str(x2.shape)) x3 = self.down_conv_2(x2) # print("x3 "+str(x3.shape)) x4 = self.max_pool_2x2(x3) # print("x4 "+str(x4.shape)) x5 = self.down_conv_3(x4) # print("x5 "+str(x5.shape)) x6 = self.max_pool_2x2(x5) # print("x6 "+str(x6.shape)) x7 = self.down_conv_4(x6) # print("x7 "+str(x7.shape)) x8 = self.max_pool_2x2(x7) # print("x8 "+str(x8.shape)) x9 = self.down_conv_5(x8) # print("x9 "+str(x9.shape)) # decoder (transposed convolutions increase the size) x = self.up_trans_1(x9) x = addPadding(x7, x) x = self.up_conv_1(torch.cat([x7, x], 1)) x = self.up_trans_2(x) x = addPadding(x5, x) x = self.up_conv_2(torch.cat([x5, x], 1)) x = self.up_trans_3(x) x = addPadding(x3, x) x = self.up_conv_3(torch.cat([x3, x], 1)) x = self.up_trans_4(x) x = addPadding(x1, x) x = self.up_conv_4(torch.cat([x1, x], 1)) x = self.out(x) # print(x.shape) return x.to(DEVICE)第三个https://github.com/milesial/Pytorch-UNet/blob/master/unet/unet_model.py
Pytorch 保存、读取和修改网络模型1.模型的保存与读取模型的保存与读取模型的保存import torch import torchvision ​ vgg16 = torchvision.models.vgg16(pretrained=False) # 保存方式1，模型结构加模型参数 torch.save(vgg16, 'vgg16_method1.pth') ​ # 保存方式2，模型参数（官方推荐） torch.save(vgg16.state_dict(), 'vgg16_method2.pth')模型的读取import torch import torchvision ​ # 保存方式1 加载模型 model1 = torch.load('vgg16_method1.pth') print(model1) ​ # 保存方式2 加载模型 -- 需要创建模型，然后再加载参数 model2 = torchvision.models.vgg16(pretrained=False) model2.load_state_dict(torch.load('vgg16_method2.pth')) print(model2)注意方法一可能会报错，只需要将定义模型的类引入即可，例如： from model_save import 2.网络模型的修改2.1 冻结模型的梯度for para in origin_model.parameters(): # 冻结整个模型的参数 para.requires_grad = False ​ # 冻结指定层的预训练参数： net.feature[26].weight.requires_grad = False2.2 在Sequential添加一层# features 为 nn.Sequential net.features.add_module('lastlayer', nn.Conv2d(512,512, kernel_size=3, stride=1, padding=1))2.3 修改Sequential中的某一层net.classifier[6] = nn.Linear(1000, 5) # 前面的 6 根据实际修改2.4 删除Sequential中的某一层直接使用nn.Sequential()对改层设置为空即可net.features[13] = nn.Sequential()2.5 删除Sequential的某些层net.features = nn.Sequential(*list(net.features.children())[:-4]) # 删除网络的后 4 层
在跑深度学习的过程中发现Python读取读取速度太慢了，后来发现是numpy和pandas的原因。尽量少用numpy和pandas直接读取数据吧。time_1 = time.time() dataset_path = 'dataset/origin_cylinder_train_dataset.csv' with open(dataset_path, 'r+', encoding='utf-8-sig') as f: data = np.loadtxt(f, delimiter=',', skiprows=0, dtype=np.float32) time_11 = time.time() print('time_11 - time_1:', time_11 - time_1) para = data[:, 0:4] # 4 个输入 real = data[:, 4:305:6] # 实部 31 个点 imag = data[:, 305:606:6] # 实部 31 个点 label = np.concatenate((real, imag), axis=1) time_12 = time.time() print('time_12 - time_11:', time_12 - time_11) time_2 = time.time() print('time_2 - time_1:', time_2 - time_1) time_3 = time.time() data_mat = loadmat('dataset/origin_cylinder.mat') time_4 = time.time() print('time_4 - time_3:', time_4 - time_3)结果time_11 - time_1: 20.45560312271118 time_12 - time_11: 0.017014026641845703 time_2 - time_1: 20.472617149353027 time_4 - time_3: 1.378253698348999
范数向量的范数可以简单形象的理解为向量的长度，或者向量到零点的距离，或者相应的两个点之间的距离。向量的范数定义：向量的范数是一个函数||x||,满足非负性||x|| >= 0，齐次性||cx|| = |c| ||x|| ，三角不等式||x+y|| <= ||x|| + ||y||。常用的向量的范数：L1范数: ||x|| 为x向量各个元素绝对值之和。L2范数: ||x||为x向量各个元素平方和的1/2次方，L2范数又称Euclidean范数或者Frobenius范数Lp范数: ||x||为x向量各个元素绝对值p次方和的1/p次方L∞范数: ||x||为x向量各个元素绝对值最大那个元素的绝对值，如下：椭球向量范数: ||x||A = sqrt[T(x)Ax]， T(x)代表x的转置。定义矩阵C 为M个模式向量的协方差矩阵， 设C’是其逆矩阵，则Mahalanobis距离定义为||x||C'= sqrt[T(x)C'x], 这是一个关于C’的椭球向量范数。距离欧式距离（对应L2范数）：最常见的两点之间或多点之间的距离表示法，又称之为欧几里得度量，它定义于欧几里得空间中。n维空间中两个点x1(x11,x12,…,x1n)与 x2(x21,x22,…,x2n)间的欧氏距离：也可以用表示成向量运算的形式：曼哈顿距离：曼哈顿距离对应L1-范数，也就是在欧几里得空间的固定直角坐标系上两点所形成的线段对轴产生的投影的距离总和。例如在平面上，坐标（x1, y1）的点P1与坐标（x2, y2）的点P2的曼哈顿距离为：，要注意的是，曼哈顿距离依赖座标系统的转度，而非系统在座标轴上的平移或映射。切比雪夫距离，若二个向量或二个点x1和x2，其坐标分别为(x11, x12, x13, ... , x1n)和(x21, x22, x23, ... , x2n)，则二者的切比雪夫距离为：d = max(|x1i - x2i|)，i从1到n。对应L∞范数。闵可夫斯基距离(Minkowski Distance)，闵氏距离不是一种距离，而是一组距离的定义。对应Lp范数，p为参数。闵氏距离的定义：两个n维变量（或者两个n维空间点）x1(x11,x12,…,x1n)与 x2(x21,x22,…,x2n)间的闵可夫斯基距离定义为：其中p是一个变参数。当p=1时，就是曼哈顿距离，当p=2时，就是欧氏距离，当p→∞时，就是切比雪夫距离，根据变参数的不同，闵氏距离可以表示一类的距离。Mahalanobis距离：也称作马氏距离。在近邻分类法中，常采用欧式距离和马氏距离。在机器学习中的应用L1范数和L2范数，用于机器学习的L1正则化、L2正则化。对于线性回归模型，使用L1正则化的模型建叫做Lasso回归，使用L2正则化的模型叫做Ridge回归（岭回归）。其作用是：L1正则化是指权值向量w中各个元素的绝对值之和，可以产生稀疏权值矩阵（稀疏矩阵指的是很多元素为0，只有少数元素是非零值的矩阵，即得到的线性回归模型的大部分系数都是0. ），即产生一个稀疏模型，可以用于特征选择；L2正则化是指权值向量w中各个元素的平方和然后再求平方根，可以防止模型过拟合（overfitting）；一定程度上，L1也可以防止过拟合。原文链接:https://blog.csdn.net/kingzone_2008/article/details/15073987
Anaconda简介Anaconda指的是一个开源的Python发行版本，其包含了conda、Python等180多个科学包及其依赖项。 因为包含了大量的科学包，Anaconda 的下载文件比较大（约 531 MB），如果只需要某些包，或者需要节省带宽或存储空间，也可以使用Miniconda这个较小的发行版（仅包含conda和 Python）。Conda是一个开源的包、环境管理器，可以用于在同一个机器上安装不同版本的软件包及其依赖，并能够在不同的环境之间切换。Anaconda包括Conda、Python以及一大堆安装好的工具包，比如：numpy、pandas等。Miniconda包括Conda、Python。总的来说Anaconda的好处在于方便管理python版本及工具包，可以针对不同的环境安装不同的包依赖以及python版本。Anaconda安装Anaconda下载方法一：官网下载地址传送门：https://www.anaconda.com/products/individual-d如果你能打开Google的话，推荐在官网下载，因为他的版本是最新的。如果不能的话使用方法二吧。方法二：镜像网站下载常用的有阿里源、清华源、豆瓣源等等。清华源下载地址传送门：https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda安装双击打开下载的安装包，按如图所示操作。如果电脑存在多个用户且需要给每个用户安装就选择All Users，否则就选择Just Me。这里自己选一个自己常用的软件安装位置即可。上面这个一定要勾选，意思是将其添加到系统的环境变量中。等待进度条完成点击Next点击skip取消两个选项，点击Finish即可。在开始菜单打开Anaconda Prompt，输入conda -V，若显示了conda的版本号，则代表安装成功。Anaconda配置源（选做）这里以清华源举例，若想配置其他源的话，可以类似操作。conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/conda config --set show_channel_urls yes可以通过来检查是否添加源成功conda config --show channels[scode type="yellow"]注意，添加源并不是必须的，如果你能顺利访问外网的话就不用添加[/scode]Anaconda环境操作创建环境conda create -n 环境名 python=python的版本号例如：conda create -n test python=3.7使用conda创建虚拟环境一定要跟上python版本，不然创建的虚拟环境还是用的base的pip，详细见：https://blog.csdn.net/qq_37640597/article/details/109638386查看当前conda所有环境conda info --envs激活环境Conda activate 环境名 Source activate 环境名 activate + 环境名删除环境conda env remove -n 环境名 ，例如* conda env remove -n flowers 克隆环境conda create -n 新环境名 --clone 所需要克隆的环境名退出当前环境conda deactivate管理环境的python版本重新安装一遍python即可，命令：conda install python=python版本号，例如conda install python=python3.7就是将环中的python版本设为python3.7。检查环境的python版本python -V管理conda查看conda版本conda --version升级conda版本conda update conda管理包查看已安装的包conda list或者pip list安装包conda install --name 环境名 包名提示：你必须告诉conda你要安装环境的名字（-n bunies）否则它将会被安装到当前环境中。如果已经激活了当前环境直接使用conda install 包名或者pip install 包名或者pip install 包名称 -i https://pypi.tuna.tsinghua.edu.cn/simple（清华镜像）或者pip install 包名称 -i https://pypi.doubanio.com/simple/ （豆瓣镜像）提示：pip只是一个包管理器，所以它不能为你管理环境。pip甚至不能升级python，因为它不像conda一样把python当做包来处理。但是它可以安装一些conda安装不了的包。移除包conda remove -n 环境名 包名或则直接在所需要移除的环境类使用conda remove 包名或者pip remove 包名[scode type="blue"]参考链接：https://blog.csdn.net/ITLearnHall/article/details/81708148https://zhuanlan.zhihu.com/p/75717350https://blog.csdn.net/fyuanfena/article/details/52080270[/scode][scode type="yellow"]如发现原文有错误请联系修改，谢谢合作[/scode]著作权归LICCOO所有。如需转载，请注明出处。欢迎到评论补充哦如需转载请标明原文链接 https://www.liccoo.com/deeplearnling/anaconda-use.html
梯度带(Gradientape)的定义TensorFlow 为自动微分提供了 tf.GradientTape API ，根据某个函数的输入变量来计算它的导数。Tensorflow 会把 tf.GradientTape 上下文中执行的所有操作都记录在一个磁带上 (tape)。 然后基于这个磁带和每次操作产生的导数，用反向微分法（“reverse mode differentiation”）来计算这些被“记录在案”的函数的导数。原文链接：https://blog.csdn.net/Forrest97/article/details/105913952