(3)融合cbam的two-stream项目搭建----双流网络搭建

双流网络搭建

在VggNet中曾表明,网络层的深度是对于学习表达能力更强的特征至关重要。但是增加深度随着带来的是duration的问题,网络性能变差,直接表现在训练集上准确率降低。
使用残差网络来搭建时空网络,可选择的网络

'ResNet''resnet18', 'resnet34', 'resnet50', 'resnet50_aux', 'resnet101', 'resnet152'
#已在ImageNet上预训练好的网络URL如下:
model_urls = {
    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',
}

2、各种ResNet网络模型
在这里插入图片描述在ResNet50、ResNet101、RestNet152中采用的是Bottleneck模块,ResNet18和ResNet32采用的是原始的Basic模块。ResNet中加入了bottleneck模块,其目的是为了减少参数计算量,从而减少模型训练时间。如下图所示,左图为BasicBlock,由两个卷积层构成,右图为Bottleneck,由三个卷积层构成,先用64个11256的卷积核对输入的特征进行降维减少通道数,再通过33的卷积核提取特征,最后再用256个11卷积核对提取到的特征进行升维,从而与输入维度保持一致。
在这里插入图片描述以下是对Basic和Bottleneck的定义。

#3*3卷积层提取特征
def conv3x3(in_planes, out_planes, stride=1):
    "3x3 convolution with padding"
    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
                     padding=1, bias=False)
class BasicBlock(nn.Module):
'''
在Bottleneck中,
首先3*3*planes个卷积核提取特征
最后3*3*planes个卷积核提取特征
因此expansion=1
'''
    expansion = 1
    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        #数据归一化
        self.bn1 = nn.BatchNorm2d(planes)
        #数据正则化,且会改变输入值
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = downsample
        self.stride = stride
    def forward(self, x):
        residual = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn2(out)
        if self.downsample is not None:
            residual = self.downsample(x)
        out += residual
        out = self.relu(out)
        return out

class Bottleneck(nn.Module):
'''
在Bottleneck中,
首先1*1*planes个卷积核进行降维
接着3*3*planes个卷积核提取特征
最后1*1*4*planes个卷积核升维
因此expansion=4
'''
    expansion = 4
    #使用1*1卷积核用来对网络进行升维和降维操作
    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        #用3*3卷积来提取特征
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
                               padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        #接着用1*1卷积核扩增维度为输入的4倍
        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(planes * 4)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride
	#定义前向传播函数
    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

		#对输入特征进行下降样来匹配上述基本块的输出out维度
        if self.downsample is not None:
            residual = self.downsample(x)
        out += residual
        out = self.relu(out)
        return out

定义ResNet网络结构

class ResNet(nn.Module):
'''
ResNet的整体结构:
conv1:7*7*64卷积核,stride=2
conv2_x:首先3*3的max pool ,stride=2,
      接着若干个BasicBlock或者Bottleneck,planes=64
conv3_x:若干个BasicBlock或者Bottleneck,planes=128
conv4_x:若干个BasicBlock或者Bottleneck,planes=256
conv5_x:若干个BasicBlock或者Bottleneck,planes=512
全连接
'''
    def __init__(self, block, layers, num_classes=1000):
        self.inplanes = 64
        super(ResNet, self).__init__()
        #######conv1
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,
                               bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        ####conv2_x
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(block, 64, layers[0])
        #####conv3_x
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
        #####conv4_x
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
        ####conv5_x
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
        ####平均池化后全连接
        self.avgpool = nn.AvgPool2d(7)
        # self.fc_aux = nn.Linear(512 * block.expansion, 101)
        self.dp = nn.Dropout(p=0.8)
        self.fc_action = nn.Linear(512 * block.expansion, num_classes)
        #对参数进行初始化
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2. / n))
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

    def _make_layer(self, block, planes, blocks, stride=1):
        downsample = None
        #不同模块的输入输出维度不同,比如conv1输出维度为64,Bottleneck的conv2_x的输入应该为64*4,但是实际输入的是64,因此对其进行采样,使其维度与模块输入维度一致。
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(
                nn.Conv2d(self.inplanes, planes * block.expansion,
                          kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(planes * block.expansion),
            )

        layers = []
        layers.append(block(self.inplanes, planes, stride, downsample))
        self.inplanes = planes * block.expansion
        for i in range(1, blocks):
            layers.append(block(self.inplanes, planes))

        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.dp(x)
        x = self.fc_action(x)

        return x

设计好ResNet类后,为每个ResNet网络实例化(赋予各个Block的类型与个数)

def rgb_resnet152(pretrained=False, **kwargs):
    """Constructs a ResNet-152 model.
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
    resnet152是由Bottleneck构成,每个Bottleneck个数为[3, 8, 36, 3]
    """
    model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs)
    if pretrained:
        #导入预训练好的resnet152
        pretrained_dict = model_zoo.load_url(model_urls['resnet152'])
        model_dict = model.state_dict()
        # 1. filter out unnecessary keys
        pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
        # 2. overwrite entries in the existing state dict
        model_dict.update(pretrained_dict) 
        # 3. load the new state dict
        model.load_state_dict(model_dict)

    return model
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
抱歉,我无法提供完整的CBAM-CNN-LSTM股票预测的Python代码,因为这涉及到一个复杂的模型架构和数据处理步骤。不过,我可以向你解释一下这个模型的主要思想和步骤,帮助你理解如何实现它。 CBAM-CNN-LSTM模型是一种结合了卷积神经网络(CNN)、循环神经网络(LSTM)和通道与空间注意力机制(CBAM)的混合模型,用于股票预测。下面是一个简单的伪代码示例,展示了CBAM-CNN-LSTM模型的主要步骤: ```python # 导入必要的库 import numpy as np import pandas as pd from keras.models import Sequential from keras.layers import LSTM, Dense, Conv1D, MaxPooling1D, GlobalAveragePooling1D # 加载和准备数据 data = pd.read_csv('stock_data.csv') # 数据预处理步骤... # 构建CBAM-CNN-LSTM模型 model = Sequential() model.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(timesteps, features))) model.add(MaxPooling1D(pool_size=2)) model.add(Conv1D(filters=128, kernel_size=3, activation='relu')) model.add(MaxPooling1D(pool_size=2)) model.add(GlobalAveragePooling1D()) model.add(LSTM(units=64)) model.add(Dense(units=1, activation='sigmoid')) # 编译和训练模型 model.compile(optimizer='adam', loss='mean_squared_error') model.fit(X_train, y_train, epochs=10, batch_size=32) # 使用模型进行预测 predictions = model.predict(X_test) # 评估模型性能 # ... ``` 这只是一个简单的示例,实际应用中可能需要更复杂的数据预处理、调参等步骤。你可以根据自己的需求和数据集进行相应的修改和调整。记得根据你的数据特性,进行适当的调整和优化,以便获得更好的预测结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃头嘤嘤魔

感谢厚爱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值