北京网站怎么建设,购物网站 英文介绍,页面设计源代码,企业网站带数据库MedMamba原理和用于糖尿病视网膜病变检测尝试
1.MedMamba原理 MedMamba发表于2024.9.28#xff0c;是构建在Vision Mamba基础之上#xff0c;融合了卷积神经网的架构#xff0c;结构如下图#xff1a; 原理简述就是图片输入后按通道输入后切分为两部分#xff0c;一部分走…MedMamba原理和用于糖尿病视网膜病变检测尝试
1.MedMamba原理 MedMamba发表于2024.9.28是构建在Vision Mamba基础之上融合了卷积神经网的架构结构如下图 原理简述就是图片输入后按通道输入后切分为两部分一部分走二维分组卷积提取局部特征一部分利用Vision Mamba中的SS2D模块提取所谓的全局特征两个分支的输出通过通道维度的拼接后经过channel shuffle增加信息融合。
2.代码解释
模型代码就在源码的MedMamba.py文件下对涉及到的代码我进行了详细注释 mamba部分 基本上是使用Vision Mamaba的SS2D
class SS2D(nn.Module):def __init__(self,d_model,d_state16,# d_stateauto, # 20240109d_conv3,expand2,dt_rankauto,dt_min0.001,dt_max0.1,dt_initrandom,dt_scale1.0,dt_init_floor1e-4,dropout0.,conv_biasTrue,biasFalse,deviceNone,dtypeNone,**kwargs,):# 设置设备和数据类型的关键参数factory_kwargs {device: device, dtype: dtype}super().__init__()self.d_model d_model # 模型维度self.d_state d_state # 状态维度# self.d_state math.ceil(self.d_model / 6) if d_state auto else d_model # 20240109self.d_conv d_conv # 卷积核的大小self.expand expand # 扩展因子self.d_inner int(self.expand * self.d_model) # 内部维度等于模型维度乘以扩展因子# 时间步长的秩默认为模型维度除以16self.dt_rank math.ceil(self.d_model / 16) if dt_rank auto else dt_rank# 输入投影层将模型维度投影到内部维度的两倍用于后续操作self.in_proj nn.Linear(self.d_model, self.d_inner * 2, biasbias, **factory_kwargs)# 深度卷积层输入和输出通道数相同组数等于内部维度用于空间特征提取self.conv2d nn.Conv2d(in_channelsself.d_inner,out_channelsself.d_inner,groupsself.d_inner,biasconv_bias,kernel_sized_conv,padding(d_conv - 1) // 2, # 保证输出的空间维度与输入相同**factory_kwargs,)self.act nn.SiLU() # 激活函数使用 SiLU# 定义多个线性投影层将内部维度投影到不同大小的向量用于时间步长和状态self.x_proj (nn.Linear(self.d_inner, (self.dt_rank self.d_state * 2), biasFalse, **factory_kwargs), nn.Linear(self.d_inner, (self.dt_rank self.d_state * 2), biasFalse, **factory_kwargs), nn.Linear(self.d_inner, (self.dt_rank self.d_state * 2), biasFalse, **factory_kwargs), nn.Linear(self.d_inner, (self.dt_rank self.d_state * 2), biasFalse, **factory_kwargs), )# 将四个线性投影层的权重合并为一个参数方便计算self.x_proj_weight nn.Parameter(torch.stack([t.weight for t in self.x_proj], dim0)) # (K4, N, inner)# 删除单独的投影层以节省内存del self.x_proj# 初始化时间步长的线性投影定义四组时间步长投影参数self.dt_projs (self.dt_init(self.dt_rank, self.d_inner, dt_scale, dt_init, dt_min, dt_max, dt_init_floor, **factory_kwargs),self.dt_init(self.dt_rank, self.d_inner, dt_scale, dt_init, dt_min, dt_max, dt_init_floor, **factory_kwargs),self.dt_init(self.dt_rank, self.d_inner, dt_scale, dt_init, dt_min, dt_max, dt_init_floor, **factory_kwargs),self.dt_init(self.dt_rank, self.d_inner, dt_scale, dt_init, dt_min, dt_max, dt_init_floor, **factory_kwargs),)# 将时间步长的权重和偏置参数合并为可训练参数self.dt_projs_weight nn.Parameter(torch.stack([t.weight for t in self.dt_projs], dim0)) # (K4, inner, rank)self.dt_projs_bias nn.Parameter(torch.stack([t.bias for t in self.dt_projs], dim0)) # (K4, inner)del self.dt_projs# 初始化 S4D 的 A 参数用于状态更新计算self.A_logs self.A_log_init(self.d_state, self.d_inner, copies4, mergeTrue) # (K4, D, N)# 初始化 D 参数用于跳跃连接的计算self.Ds self.D_init(self.d_inner, copies4, mergeTrue) # (K4, D, N)# 选择核心的前向计算函数版本默认为 forward_corev0# self.selective_scan selective_scan_fnself.forward_core self.forward_corev0# 输出层的层归一化归一化到内部维度self.out_norm nn.LayerNorm(self.d_inner)# 输出投影层将内部维度投影回原始模型维度self.out_proj nn.Linear(self.d_inner, self.d_model, biasbias, **factory_kwargs)# 设置 dropout 层如果 dropout 参数大于 0则应用随机失活以防止过拟合self.dropout nn.Dropout(dropout) if dropout 0. else Nonestaticmethoddef dt_init(dt_rank, d_inner, dt_scale1.0, dt_initrandom, dt_min0.001, dt_max0.1, dt_init_floor1e-4, **factory_kwargs):dt_proj nn.Linear(dt_rank, d_inner, biasTrue, **factory_kwargs)# 初始化用于时间步长计算的线性投影层# Initialize special dt projection to preserve variance at initialization# 特殊初始化方法用于保持初始化时的方差不变dt_init_std dt_rank**-0.5 * dt_scaleif dt_init constant: # 初始化为常数nn.init.constant_(dt_proj.weight, dt_init_std)elif dt_init random: # 初始化为均匀随机数nn.init.uniform_(dt_proj.weight, -dt_init_std, dt_init_std)else:raise NotImplementedError# Initialize dt bias so that F.softplus(dt_bias) is between dt_min and dt_max# 初始化偏置以便在使用 F.softplus 时结果处于 dt_min 和 dt_max 之间dt torch.exp(torch.rand(d_inner, **factory_kwargs) * (math.log(dt_max) - math.log(dt_min)) math.log(dt_min)).clamp(mindt_init_floor)# Inverse of softplus: https://github.com/pytorch/pytorch/issues/72759# softplus 的逆操作确保偏置初始化在合适范围内inv_dt dt torch.log(-torch.expm1(-dt))with torch.no_grad():dt_proj.bias.copy_(inv_dt) # 设置偏置参数# Our initialization would set all Linear.bias to zero, need to mark this one as _no_reinitdt_proj.bias._no_reinit True # 将该偏置标记为不重新初始化return dt_projSS_Conv_SSM 这部分就是论文提出的创新点图片中的结构 class SS_Conv_SSM(nn.Module):def __init__(self,hidden_dim: int 0,drop_path: float 0,norm_layer: Callable[..., torch.nn.Module] partial(nn.LayerNorm, eps1e-6),attn_drop_rate: float 0,d_state: int 16,**kwargs,):super().__init__()# 初始化第一个归一化层归一化的维度是隐藏维度的一半self.ln_1 norm_layer(hidden_dim//2)# 初始化自注意力模块 SS2D输入维度为隐藏维度的一半self.self_attention SS2D(d_modelhidden_dim//2,dropoutattn_drop_rate,d_stated_state,**kwargs)# DropPath 层用于随机丢弃路径提高模型的泛化能力self.drop_path DropPath(drop_path)# 定义卷积模块由多个卷积层和批量归一化层组成用于特征提取self.conv33conv33conv11 nn.Sequential(nn.BatchNorm2d(hidden_dim // 2),nn.Conv2d(in_channelshidden_dim//2,out_channelshidden_dim//2,kernel_size3,stride1,padding1),nn.BatchNorm2d(hidden_dim//2),nn.ReLU(),nn.Conv2d(in_channelshidden_dim // 2, out_channelshidden_dim // 2, kernel_size3, stride1, padding1),nn.BatchNorm2d(hidden_dim // 2),nn.ReLU(),nn.Conv2d(in_channelshidden_dim // 2, out_channelshidden_dim // 2, kernel_size1, stride1),nn.ReLU())# 注释掉的最终卷积层可能用于进一步调整输出维度# self.finalconv11 nn.Conv2d(in_channelshidden_dim, out_channelshidden_dim, kernel_size1, stride1)def forward(self, input: torch.Tensor):# 将输入张量沿最后一个维度分割为左右两部分input_left, input_right input.chunk(2,dim-1)# 对右侧输入进行归一化和自注意力操作之后应用 DropPath 随机丢弃x self.drop_path(self.self_attention(self.ln_1(input_right)))# 将左侧输入从 (batch_size, height, width, channels)# 转换为 (batch_size, channels, height, width) 以适应卷积操作input_left input_left.permute(0,3,1,2).contiguous()input_left self.conv33conv33conv11(input_left)# 将卷积后的左侧输入转换回原来的形状 (batch_size, height, width, channels)input_left input_left.permute(0,2,3,1).contiguous()# 将左侧和右侧的输出在最后一个维度上拼接起来output torch.cat((input_left,x),dim-1)# 对拼接后的输出进行通道混洗增加特征的融合output channel_shuffle(output,groups2)# 返回最终的输出增加残差连接将输入与输出相加return outputinputVSSLayer 有以上结构堆叠构成网络结构 class VSSLayer(nn.Module): A basic Swin Transformer layer for one stage.Args:dim (int): Number of input channels.depth (int): Number of blocks.drop (float, optional): Dropout rate. Default: 0.0attn_drop (float, optional): Attention dropout rate. Default: 0.0drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNormdownsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: Noneuse_checkpoint (bool): Whether to use checkpointing to save memory. Default: False.def __init__(self, dim, depth, attn_drop0.,drop_path0., norm_layernn.LayerNorm, downsampleNone, use_checkpointFalse, d_state16,**kwargs,):super().__init__()# 设置输入通道数self.dim dim# 是否使用检查点self.use_checkpoint use_checkpoint# 创建 SS_Conv_SSM 块列表数量为 depthself.blocks nn.ModuleList([SS_Conv_SSM(hidden_dimdim, # 隐藏层维度等于输入维度# 处理随机深度的丢弃率drop_pathdrop_path[i] if isinstance(drop_path, list) else drop_path,norm_layernorm_layer, # 使用的归一化层attn_drop_rateattn_drop, # 注意力丢弃率d_stated_state, # 状态维度)for i in range(depth)]) # 重复 depth 次构建块# 初始化权重 (暂时没有真正初始化可能在后续被重写)# 确保这一初始化应用于模型 (在 VSSM 中被覆盖)if True: # is this really applied? Yes, but been overriden later in VSSM!# 对每个模块的参数进行初始化def _init_weights(module: nn.Module):for name, p in module.named_parameters():if name in [out_proj.weight]:# 克隆并分离参数 p用于保持随机数种子一致p p.clone().detach_() # fake init, just to keep the seed ....# 使用 Kaiming 均匀初始化方法nn.init.kaiming_uniform_(p, amath.sqrt(5))# 应用初始化函数到整个模型self.apply(_init_weights)# 如果提供了下采样层则使用该层否则设置为 Noneif downsample is not None:self.downsample downsample(dimdim, norm_layernorm_layer)else:self.downsample Nonedef forward(self, x):# 逐块应用 SS_Conv_SSM 模块for blk in self.blocks:# 如果使用检查点则通过检查点执行前向传播节省内存if self.use_checkpoint:x checkpoint.checkpoint(blk, x)else:# 否则直接进行前向传播x blk(x)# 如果存在下采样层则应用下采样层if self.downsample is not None:x self.downsample(x)# 返回最终的输出张量return x最终的网络模型类 class VSSM(nn.Module):def __init__(self, patch_size4, in_chans3, num_classes1000, depths[2, 2, 4, 2], depths_decoder[2, 9, 2, 2],dims[96,192,384,768], dims_decoder[768, 384, 192, 96], d_state16, drop_rate0., attn_drop_rate0., drop_path_rate0.1,norm_layernn.LayerNorm, patch_normTrue,use_checkpointFalse, **kwargs):super().__init__()self.num_classes num_classes # 设置分类的类别数目self.num_layers len(depths) # 设置层的数量即编码器层的数量# 如果 dims 是一个整数则自动扩展为一个包含每一层维度的列表if isinstance(dims, int):dims [int(dims * 2 ** i_layer) for i_layer in range(self.num_layers)]self.embed_dim dims[0] # 嵌入维度等于第一层的维度self.num_features dims[-1] # 特征维度等于最后一层的维度self.dims dims # 记录每一层的维度# 初始化补丁嵌入模块将输入图像分割成补丁并进行线性投影self.patch_embed PatchEmbed2D(patch_sizepatch_size, in_chansin_chans, embed_dimself.embed_dim,norm_layernorm_layer if patch_norm else None)# WASTED absolute position embedding # 是否使用绝对位置编码默认情况下不使用self.ape False# self.ape False# drop_rate 0.0# 如果使用绝对位置编码则初始化位置编码参数if self.ape:self.patches_resolution self.patch_embed.patches_resolution# 创建位置编码的可训练参数并进行截断正态分布初始化self.absolute_pos_embed nn.Parameter(torch.zeros(1, *self.patches_resolution, self.embed_dim))trunc_normal_(self.absolute_pos_embed, std.02)# 位置编码的 Dropout 层self.pos_drop nn.Dropout(pdrop_rate)# 使用线性函数生成每层的随机深度丢弃率dpr [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # 随机深度衰减规则# 解码器部分的随机深度衰减dpr_decoder [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths_decoder))][::-1]# 初始化编码器的层列表self.layers nn.ModuleList()for i_layer in range(self.num_layers): # 创建每一层的 VSSLayerlayer VSSLayer(dimdims[i_layer], # 输入维度depthdepths[i_layer], # 当前层包含的块数量d_statemath.ceil(dims[0] / 6) if d_state is None else d_state, # 状态维度dropdrop_rate, # Dropout率attn_dropattn_drop_rate, # 注意力 Dropout率# 当前层的随机深度丢弃率drop_pathdpr[sum(depths[:i_layer]):sum(depths[:i_layer 1])],# 归一化层类型norm_layernorm_layer,# 下采样层最后一层不进行下采样downsamplePatchMerging2D if (i_layer self.num_layers - 1) else None,# 是否使用检查点技术节省内存use_checkpointuse_checkpoint,)# 将层添加到层列表中self.layers.append(layer)# self.norm norm_layer(self.num_features)# 平均池化层用于将特征池化为单个值self.avgpool nn.AdaptiveAvgPool2d(1)# 分类头部使用线性层将特征映射到类别数目self.head nn.Linear(self.num_features, num_classes) if num_classes 0 else nn.Identity()# 初始化模型权重self.apply(self._init_weights)# 对模型中的卷积层进行 Kaiming 正态分布初始化for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, modefan_out, nonlinearityrelu)def _init_weights(self, m: nn.Module):out_proj.weight which is previously initilized in SS_Conv_SSM, would be cleared in nn.Linearno fc.weight found in the any of the model parametersno nn.Embedding found in the any of the model parametersso the thing is, SS_Conv_SSM initialization is uselessConv2D is not intialized !!!# 对线性层和归一化层进行权重初始化if isinstance(m, nn.Linear):# 对线性层的权重使用截断正态分布初始化trunc_normal_(m.weight, std.02)# 如果存在偏置则将其初始化为 0if isinstance(m, nn.Linear) and m.bias is not None:nn.init.constant_(m.bias, 0)elif isinstance(m, nn.LayerNorm):# 对 LayerNorm 层的偏置和权重初始化nn.init.constant_(m.bias, 0)nn.init.constant_(m.weight, 1.0)torch.jit.ignoredef no_weight_decay(self):# 返回不需要权重衰减的参数名return {absolute_pos_embed}torch.jit.ignoredef no_weight_decay_keywords(self):# 返回不需要权重衰减的关键字return {relative_position_bias_table}def forward_backbone(self, x):# 使用补丁嵌入模块处理输入张量x self.patch_embed(x)if self.ape:# 如果使用绝对位置编码则将位置编码加到输入特征上x x self.absolute_pos_embed# 位置编码之后应用 Dropoutx self.pos_drop(x)# 逐层通过编码器层for layer in self.layers:x layer(x)return xdef forward(self, x):# 通过骨干网络提取特征x self.forward_backbone(x)# 变换维度以适应池化操x x.permute(0,3,1,2)# 使用自适应平均池化将特征降维x self.avgpool(x)# 展平成一个向量x torch.flatten(x,start_dim1)# 通过分类头进行最终的类别预测x self.head(x)return x作者在原文中尝试了大中小三个不同的参数版本 medmamba_t VSSM(depths[2, 2, 4, 2],dims[96,192,384,768],num_classes6).to(cuda)
medmamba_s VSSM(depths[2, 2, 8, 2],dims[96,192,384,768],num_classes6).to(cuda)
medmamba_b VSSM(depths[2, 2, 12, 2],dims[128,256,512,1024],num_classes6).to(cuda)总体论文原理比较简单但是论文实验做得很扎实感兴趣查看原文。
3.在糖尿病视网膜数据上实验一下效果
数据集情况
采用开源的retino_data糖尿病视网膜病变数据集 环境安装
这部分主要是vision mamba的环境安装不要出错参考官方Github会有问题 Python 3.10.13 conda create -n vim python3.10.13 torch 2.1.1 cu118 pip install torch2.1.1 torchvision0.16.1 torchaudio2.1.1 --index-url https://download.pytorch.org/whl/cu118 Requirements: vim_requirements.txt pip install -r vim/vim_requirements.txt
wget https://github.com/Dao-AILab/causal-conv1d/releases/download/v1.1.3.post1/causal_conv1d-1.1.3.post1cu118torch2.1cxx11abiFALSE-cp310-cp310-linux_x86_64.whl wget https://github.com/state-spaces/mamba/releases/download/v1.1.1/mamba_ssm-1.1.1cu118torch2.1cxx11abiFALSE-cp310-cp310-linux_x86_64.whl pip install causal_conv1d-1.1.3.post1cu118torch2.1cxx11abiFALSE-cp310-cp310-linux_x86_64.whl pip install mamba_ssm-1.1.1cu118torch2.1cxx11abiFALSE-cp310-cp310-linux_x86_64.whl 然后用官方项目里的mamba_ssm替换安装在conda环境里的mamba_ssm 用conda env list 查看刚才安装的mamba环境的路径我的mamba环境在/home/aic/anaconda3/envs/vim 用官方项目里的mamba_ssm替换安装在conda环境里的mamba_ssm cp -rf mamba-1p1p1/mamba_ssm /home/aic/anaconda3/envs/vim/lib/python3.10/site-packages
代码编写
编写一个检查数据集均值和方差的代码不用Imagenet的
# -*- coding: utf-8 -*-
# 作者: cskywit
# 文件名: mean_std.py
# 创建时间: 2024-10-07
# 文件描述计算数据集的均值和方差# 导入必要的库
from torchvision.datasets import ImageFolder
import torch
from torchvision import transforms# 定义函数get_mean_and_std用于计算训练数据集的均值和标准差
def get_mean_and_std(train_data):# 创建DataLoader用于批量加载数据train_loader torch.utils.data.DataLoader(train_data, batch_size1, shuffleFalse, num_workers0,pin_memoryTrue)# 初始化均值和标准差mean torch.zeros(3)std torch.zeros(3)# 遍历数据集中的每个批次for X, _ in train_loader:# 遍历RGB三个通道for d in range(3):# 计算每个通道的均值和标准差mean[d] X[:, d, :, :].mean()std[d] X[:, d, :, :].std()# 计算最终的均值和标准差mean.div_(len(train_data))std.div_(len(train_data))# 返回均值和标准差列表return list(mean.numpy()), list(std.numpy())# 判断是否为主程序
if __name__ __main__:root_path /home/aic/deep_learning_data/retino_data/train# 使用ImageFolder加载训练数据集train_dataset ImageFolder(rootroot_path, transformtransforms.ToTensor())# 打印训练数据集的均值和标准差print(get_mean_and_std(train_dataset))# ([0.41586006, 0.22244255, 0.07565845],# [0.23795983, 0.13206834, 0.05284985])然后编写train
# -*- coding: utf-8 -*-
# 作者: cskywit
# 文件名: train_DR.py
# 创建时间: 2024-10-10
# 文件描述
import torch
import torch.nn as nn
from torchvision import transforms, datasets
import torch.optim as optim
from tqdm import tqdmfrom MedMamba import VSSM as medmamba # import model
import warnings
import os,syswarnings.filterwarnings(ignore)
os.environ[CUDA_VISIBLE_DEVICES]0# 设置随机因子
def seed_everything(seed42):os.environ[PYHTONHASHSEED] str(seed)torch.manual_seed(seed)torch.cuda.manual_seed(seed)torch.backends.cudnn.deterministic Truedef main():# 设置随机因子seed_everything()# 一些超参数设定num_classes 2BATCH_SIZE 64num_of_workers min([os.cpu_count(), BATCH_SIZE if BATCH_SIZE 1 else 0, 8]) # number of workersdevice torch.device(cuda:0 if torch.cuda.is_available() else cpu)epochs 300best_acc 0.0save_path ./{}.pth.format(bestmodel)# 数据预处理transform transforms.Compose([transforms.RandomRotation(10),transforms.GaussianBlur(kernel_size(5, 5), sigma(0.1, 3.0)),transforms.ColorJitter(brightness0.5, contrast0.5, saturation0.5),transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(mean[0.41593555, 0.22245076, 0.075719066],std[0.23819199, 0.13202211, 0.05282707])])transform_test transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(mean[0.41593555, 0.22245076, 0.075719066],std[0.23819199, 0.13202211, 0.05282707])])# 加载数据集root_path /home/aic/deep_learning_data/retino_datatrain_path os.path.join(root_path, train)valid_path os.path.join(root_path, valid)test_path os.path.join(root_path, test)dataset_train datasets.ImageFolder(train_path, transformtransform)dataset_valid datasets.ImageFolder(valid_path, transformtransform_test)dataset_test datasets.ImageFolder(test_path, transformtransform_test)class_labels {0: Diabetic Retinopathy, 1: No Diabetic Retinopathy}val_num len(dataset_valid)train_loader torch.utils.data.DataLoader(dataset_train, batch_sizeBATCH_SIZE,num_workersnum_of_workers,shuffleTrue,drop_lastTrue)valid_loader torch.utils.data.DataLoader(dataset_valid,batch_sizeBATCH_SIZE,num_workersnum_of_workers,shuffleFalse,drop_lastTrue)test_loader torch.utils.data.DataLoader(dataset_test,batch_sizeBATCH_SIZE,shuffleFalse)print(Using {} dataloader workers every process.format(num_of_workers))# 模型定义net medmamba(num_classesnum_classes).to(device)loss_function nn.CrossEntropyLoss()optimizer optim.Adam(net.parameters(), lr0.0001)train_steps len(train_loader)for epoch in range(epochs):# trainnet.train()running_loss 0.0train_bar tqdm(train_loader, filesys.stdout)for step, data in enumerate(train_bar):images, labels dataoptimizer.zero_grad()outputs net(images.to(device))loss loss_function(outputs, labels.to(device))loss.backward()optimizer.step()# print statisticsrunning_loss loss.item()train_bar.desc train epoch[{}/{}] loss:{:.3f}.format(epoch 1,epochs,loss)# validatenet.eval()acc 0.0 # accumulate accurate number / epochwith torch.no_grad():val_bar tqdm(valid_loader, filesys.stdout)for val_data in val_bar:val_images, val_labels val_dataoutputs net(val_images.to(device))predict_y torch.max(outputs, dim1)[1]acc torch.eq(predict_y, val_labels.to(device)).sum().item()val_accurate acc / val_numprint([epoch %d] train_loss: %.3f val_accuracy: %.3f %(epoch 1, running_loss / train_steps, val_accurate))if val_accurate best_acc:best_acc val_accuratetorch.save(net.state_dict(), save_path)print(Finished Training)if __name__ __main__:main()感觉Mamaba系列的通病了吧显存占用不算高GPU利用率超高 可能是没有用任何的训练调参技巧经过几个epoch后验证集准确率很快提升到了92.3%,然后就没有继续上升了。 文章转载自: http://www.morning.wdpt.cn.gov.cn.wdpt.cn http://www.morning.yxnfd.cn.gov.cn.yxnfd.cn http://www.morning.ntqnt.cn.gov.cn.ntqnt.cn http://www.morning.deupp.com.gov.cn.deupp.com http://www.morning.wtlyr.cn.gov.cn.wtlyr.cn http://www.morning.rwzmz.cn.gov.cn.rwzmz.cn http://www.morning.dsxgc.cn.gov.cn.dsxgc.cn http://www.morning.ywtbk.cn.gov.cn.ywtbk.cn http://www.morning.qrwjb.cn.gov.cn.qrwjb.cn http://www.morning.lqynj.cn.gov.cn.lqynj.cn http://www.morning.rrxmm.cn.gov.cn.rrxmm.cn http://www.morning.cfmrb.cn.gov.cn.cfmrb.cn http://www.morning.swsrb.cn.gov.cn.swsrb.cn http://www.morning.bnqcm.cn.gov.cn.bnqcm.cn http://www.morning.qkrz.cn.gov.cn.qkrz.cn http://www.morning.cwkcq.cn.gov.cn.cwkcq.cn http://www.morning.tbnpn.cn.gov.cn.tbnpn.cn http://www.morning.rahllp.com.gov.cn.rahllp.com http://www.morning.cywf.cn.gov.cn.cywf.cn http://www.morning.nnhfz.cn.gov.cn.nnhfz.cn http://www.morning.ktmbp.cn.gov.cn.ktmbp.cn http://www.morning.srnth.cn.gov.cn.srnth.cn http://www.morning.nzdks.cn.gov.cn.nzdks.cn http://www.morning.bssjz.cn.gov.cn.bssjz.cn http://www.morning.nyqb.cn.gov.cn.nyqb.cn http://www.morning.srrzb.cn.gov.cn.srrzb.cn http://www.morning.yqhdy.cn.gov.cn.yqhdy.cn http://www.morning.stbhn.cn.gov.cn.stbhn.cn http://www.morning.nwjzc.cn.gov.cn.nwjzc.cn http://www.morning.xysdy.cn.gov.cn.xysdy.cn http://www.morning.zcnfm.cn.gov.cn.zcnfm.cn http://www.morning.rjnky.cn.gov.cn.rjnky.cn http://www.morning.yqgbw.cn.gov.cn.yqgbw.cn http://www.morning.rttp.cn.gov.cn.rttp.cn http://www.morning.rstrc.cn.gov.cn.rstrc.cn http://www.morning.kndyz.cn.gov.cn.kndyz.cn http://www.morning.plqqp.cn.gov.cn.plqqp.cn http://www.morning.ssjtr.cn.gov.cn.ssjtr.cn http://www.morning.lqlc.cn.gov.cn.lqlc.cn http://www.morning.vaqmq.cn.gov.cn.vaqmq.cn http://www.morning.rwzkp.cn.gov.cn.rwzkp.cn http://www.morning.wnywk.cn.gov.cn.wnywk.cn http://www.morning.wsrcy.cn.gov.cn.wsrcy.cn http://www.morning.rnqyy.cn.gov.cn.rnqyy.cn http://www.morning.jhxtm.cn.gov.cn.jhxtm.cn http://www.morning.hxpsp.cn.gov.cn.hxpsp.cn http://www.morning.nlgnk.cn.gov.cn.nlgnk.cn http://www.morning.qjbxt.cn.gov.cn.qjbxt.cn http://www.morning.dqrpz.cn.gov.cn.dqrpz.cn http://www.morning.dydqh.cn.gov.cn.dydqh.cn http://www.morning.mllmm.cn.gov.cn.mllmm.cn http://www.morning.mcpby.cn.gov.cn.mcpby.cn http://www.morning.ddfp.cn.gov.cn.ddfp.cn http://www.morning.gidmag.com.gov.cn.gidmag.com http://www.morning.wwznd.cn.gov.cn.wwznd.cn http://www.morning.rcbdn.cn.gov.cn.rcbdn.cn http://www.morning.ggnfy.cn.gov.cn.ggnfy.cn http://www.morning.xinxianzhi005.com.gov.cn.xinxianzhi005.com http://www.morning.tkgjl.cn.gov.cn.tkgjl.cn http://www.morning.lzjxn.cn.gov.cn.lzjxn.cn http://www.morning.gbgdm.cn.gov.cn.gbgdm.cn http://www.morning.zhiheliuxue.com.gov.cn.zhiheliuxue.com http://www.morning.yhdqq.cn.gov.cn.yhdqq.cn http://www.morning.mtgkq.cn.gov.cn.mtgkq.cn http://www.morning.slysg.cn.gov.cn.slysg.cn http://www.morning.ktdqu.cn.gov.cn.ktdqu.cn http://www.morning.skkmz.cn.gov.cn.skkmz.cn http://www.morning.tmpsc.cn.gov.cn.tmpsc.cn http://www.morning.ttxnj.cn.gov.cn.ttxnj.cn http://www.morning.dbnpz.cn.gov.cn.dbnpz.cn http://www.morning.yxdrf.cn.gov.cn.yxdrf.cn http://www.morning.lrjtx.cn.gov.cn.lrjtx.cn http://www.morning.pbygt.cn.gov.cn.pbygt.cn http://www.morning.qcrhb.cn.gov.cn.qcrhb.cn http://www.morning.oioini.com.gov.cn.oioini.com http://www.morning.qzbwmf.cn.gov.cn.qzbwmf.cn http://www.morning.xcjbk.cn.gov.cn.xcjbk.cn http://www.morning.jpqmq.cn.gov.cn.jpqmq.cn http://www.morning.wbxr.cn.gov.cn.wbxr.cn http://www.morning.fhkr.cn.gov.cn.fhkr.cn