时空序列预测模型—PredRNN(Pytorch)

https://cloud.tencent.com/developer/article/1622038
(强对流天气临近预报)时空序列预测模型—PredRNN(Pytorch)

代码分为3文件:

PredRNN_Cell.py #细胞单元

PredRNN_Model.py #细胞单元堆叠而成的主干模型

PredRNN_Main_Seq2seq_test.py #用于外推的Seq2seq 编码解码

# PredRNN_Cell
import torch.nn as nn
from torch.autograd import Variable
import torch
####################################
#
# 单层,单时间步的PredRNNCell(细胞/单元),用于构造整个外推模型
# The cell/unit of predrnncell of every layer and time_step, for constructing the entire extrapolation model.
#
####################################
class PredRNNCell(nn.Module):def __init__(self, input_size, input_dim, hidden_dim_m, hidden_dim,kernel_size, bias):super(PredRNNCell, self).__init__()self.height, self.width = input_sizeself.input_dim = input_dimself.hidden_dim = hidden_dimself.hidden_dim_m = hidden_dim_m   #  hidden of Mself.kernel_size = kernel_sizeself.padding = kernel_size[0] // 2, kernel_size[1] // 2self.bias = bias###################################################################################### 相应符号可对应参照论文# Corresponding symbols can correspond to reference paper# conv_h_c for gt, it, ft# conv_m for gt', it', ft'# conv_o for ot# self.conv_h_next for Htself.conv_h_c = nn.Conv2d(in_channels=self.input_dim + self.hidden_dim,out_channels=3 * self.hidden_dim,kernel_size=self.kernel_size,padding=self.padding,bias=self.bias)self.conv_m = nn.Conv2d(in_channels=self.input_dim + self.hidden_dim_m,out_channels=3 * self.hidden_dim_m,kernel_size=self.kernel_size,padding=self.padding,bias=self.bias)self.conv_o = nn.Conv2d(in_channels=self.input_dim + self.hidden_dim * 2 + self.hidden_dim_m,out_channels=self.hidden_dim,kernel_size=self.kernel_size,padding=self.padding,bias=self.bias)self.conv_h_next = nn.Conv2d(in_channels=self.hidden_dim + self.hidden_dim_m,out_channels=self.hidden_dim,kernel_size=1,bias=self.bias)def forward(self, input_tensor, cur_state, cur_state_m):h_cur, c_cur= cur_state  #cur = Current input of H and Ch_cur_m = cur_state_m #cur = Current input of mcombined_h_c = torch.cat([input_tensor,h_cur], dim=1)combined_h_c = self.conv_h_c(combined_h_c)cc_i, cc_f, cc_g = torch.split(combined_h_c, self.hidden_dim, dim=1)combined_m = torch.cat([input_tensor,  h_cur_m], dim=1)combined_m = self.conv_m(combined_m)cc_i_m, cc_f_m, cc_g_m = torch.split(combined_m, self.hidden_dim_m, dim=1)i = torch.sigmoid(cc_i)f = torch.sigmoid(cc_f)g = torch.tanh(cc_g)c_next = f * c_cur + i * gi_m = torch.sigmoid(cc_i_m)f_m = torch.sigmoid(cc_f_m)g_m = torch.tanh(cc_g_m)h_next_m = f_m * h_cur_m + i_m * g_mcombined_o = torch.cat([input_tensor, h_cur, c_next, h_next_m], dim=1)combined_o = self.conv_o(combined_o)o = torch.sigmoid(combined_o)h_next = torch.cat([c_next, h_next_m], dim=1)h_next = self.conv_h_next(h_next)h_next = o * torch.tanh(h_next)return h_next, c_next, h_next_m####################################### 用于在t=0时刻时初始化H,C,M# For initializing H,C,M at t=0######################################def init_hidden(self, batch_size):return (Variable(torch.zeros(batch_size, self.hidden_dim, self.height, self.width)).cuda(),Variable(torch.zeros(batch_size, self.hidden_dim, self.height, self.width)).cuda())
#PredRNN_Model
import torch.nn as nn
import torch
import numpy as np
from torch.autograd import Variable
from PredRNN_Cell import PredRNNCell
##############################################
#
# 构造PredRNN
# Construct PredRNN
#
##############################################
class PredRNN(nn.Module):def __init__(self, input_size, input_dim, hidden_dim, hidden_dim_m, kernel_size, num_layers,batch_first=False, bias=True):super(PredRNN, self).__init__()self._check_kernel_size_consistency(kernel_size)kernel_size = self._extend_for_multilayer(kernel_size, num_layers) # 按照层数来扩充 卷积核尺度/可自定义hidden_dim = self._extend_for_multilayer(hidden_dim, num_layers) # 按照层数来扩充 LSTM单元隐藏层维度/可自定义hidden_dim_m = self._extend_for_multilayer(hidden_dim_m, num_layers)  # M的单元应保持每层输入和输出的一致性.if not len(kernel_size) == len(hidden_dim) == num_layers:  # 判断相应参数的长度是否与层数相同raise ValueError('Inconsistent list length.')self.height, self.width = input_sizeself.input_dim = input_dimself.hidden_dim = hidden_dimself.hidden_dim_m = hidden_dim_mself.kernel_size = kernel_sizeself.num_layers = num_layersself.batch_first = batch_firstself.bias = biascell_list = []for i in range(0, self.num_layers):if i == 0:    # 0 时刻, 图片的输入即目前实际输入cur_input_dim = self.input_dimelse:cur_input_dim = self.hidden_dim[i - 1]  # 非0时刻,输入的维度为上一层的输出#Cell_list.appenda为堆叠层操作cell_list.append(PredRNNCell(input_size=(self.height, self.width),input_dim=cur_input_dim,hidden_dim=self.hidden_dim[i],hidden_dim_m=self.hidden_dim_m[i],kernel_size=self.kernel_size[i],bias=self.bias).cuda())self.cell_list = nn.ModuleList(cell_list)#Cell_list进行Model化def forward(self, input_tensor, hidden_state=False, hidden_state_m=False):if self.batch_first is False:input_tensor = input_tensor.permute(1, 0, 2, 3, 4)if hidden_state is not False:hidden_state = hidden_stateelse:   #如果没有输入自定义的权重,就以0元素来初始化hidden_state = self._init_hidden(batch_size=input_tensor.size(0))if hidden_state_m is False:h_m = Variable(torch.zeros(input_tensor.shape[0], self.hidden_dim_m[0],input_tensor.shape[3], input_tensor.shape[4]),requires_grad=True).cuda()else:h_m = hidden_state_mlayer_output_list = []  #记录输出layer_output_list_m = []  # 记录每一层mlayer_output_list_c = []  # 记录每一层clast_state_list = []  #记录最后一个状态layer_output_list_m = []  # 记录最后一个mlast_state_list_m = []  # 记录最后一个mseq_len = input_tensor.size(1)   #第二个时间序列,3cur_layer_input_1 = input_tensor #x方向上的输入all_layer_out = []for t in range(seq_len):concat=[]output_inner_c = []  # 记录输出的coutput_inner = []  #记录输出的coutput_inner_m = []  # 记录输出的moutput_inner_h_c=[] # 记录输出的h 和ch0 = cur_layer_input_1[:, t, :, :, :]  #确定layer = 1 时的输入,如雷达回波图等矩阵信息for layer_idx in range(self.num_layers): # 由于M在layer上传递,所以优先考虑layer上的传递if t == 0:  # 由于M在layer上传递,所以要区分t=0(此时m初始化)h, c = hidden_state[layer_idx]  # h和c来自于初始化/自定义h, c, h_m = self.cell_list[layer_idx](input_tensor=h0,cur_state=[h, c], cur_state_m=h_m)#经过一个cell/units输出的h,c,moutput_inner_c.append(c) #记录输出的c进行output_inner.append(h)output_inner_m.append(h_m)output_inner_h_c.append([h,c])h0=helse:h = cur_layer_input[layer_idx]c = cur_layer_input_c[layer_idx]h, c, h_m = self.cell_list[layer_idx](input_tensor=h0,cur_state=[h, c], cur_state_m=h_m)output_inner_c.append(c)output_inner.append(h)output_inner_m.append(h_m)output_inner_h_c.append([h, c])h0 = hcur_layer_input = output_inner#记录某个t,全部layer的输出hcur_layer_input_c = output_inner_c#记录某个t,全部layer的输出ccur_layer_input_m = output_inner_m#记录某个t,全部layer的输出malllayer_output = torch.cat(output_inner, dim=1) #把某个t时刻每个隐藏层的输出进行堆叠,以便于在解码层参照Convlstm使用1x1卷积得到输出all_layer_out.append(alllayer_output)#记录每个t时刻,所有隐藏层输出的h,以便于在解码层参照Convlstm使用1x1卷积得到输出per_time_all_layer_stack_out=torch.stack(all_layer_out, dim=1)#记录每个t时刻,所有隐藏层输出的h,以便于在解码层参照Convlstm使用1x1卷积得到输出layer_output_list.append(h)# 记录每一个t得到的最后layer的输出hlast_state_list.append([h, c])#记录每一个t得到的最后layer的输出h,Clast_state_list_m.append(h_m)#记录每一个t得到的最后layer的输出m#按层对最后一层的H和C进行扩展# ↓↓↓↓↓↓↓↓↓全部t时刻最后layer的输出h# ↓↓↓↓↓↓↓↓↓最后t时刻全部layer的输出h和c# ↓↓↓↓↓↓↓↓↓全部t时刻最后layer的输出m/t+1时刻0 layer的输入m# ↓↓↓↓↓↓↓↓↓全部时刻全部layer的h在隐藏层维度上的总和,hidden_dim = [7,1],则输出channels = 8return torch.stack(layer_output_list, dim=1),\output_inner_h_c,\torch.stack(last_state_list_m, dim=0),\per_time_all_layer_stack_outdef _init_hidden(self, batch_size):init_states = []for i in range(self.num_layers):init_states.append(self.cell_list[i].init_hidden(batch_size))return init_states@staticmethoddef _check_kernel_size_consistency(kernel_size):if not (isinstance(kernel_size, tuple) or(isinstance(kernel_size, list) and all([isinstance(elem, tuple) for elem in kernel_size]))):raise ValueError('`kernel_size` must be tuple or list of tuples')@staticmethoddef _extend_for_multilayer(param, num_layers):if not isinstance(param, list):param = [param] * num_layersreturn param
#PredRNN_Seq2Seq
from PredRNN_Model import PredRNN
import torch.optim as optim
import torch.nn as nn
import matplotlib.pyplot as plt
import numpy as np
from torch.autograd import Variable
import torch
from PIL import Image
from torch.utils.data import Dataset, DataLoader
import os
import timeinput=torch.rand(1,1,1,100,100).cuda()   # Batch_size , time_step, channels, hight/width, width/hight
target=torch.rand(1,1,1,100,100).cuda()   # Batch_size , time_step, channels, hight/width, width/hightclass PredRNN_enc(nn.Module):def __init__(self):super(PredRNN_enc, self).__init__()self.pred1_enc=PredRNN(input_size=(100,100),input_dim=1,hidden_dim=[7, 1],hidden_dim_m=[7, 7],kernel_size=(7, 7),num_layers=2,batch_first=True,bias=True).cuda()def forward(self,enc_input):_, layer_h_c, all_time_h_m, _ = self.pred1_enc(enc_input)return layer_h_c, all_time_h_m
class PredRNN_dec(nn.Module):def __init__(self):super(PredRNN_dec, self).__init__()self.pred1_dec=PredRNN(input_size=(100,100),input_dim=1,hidden_dim=[7, 1],hidden_dim_m=[7, 7],kernel_size=(7, 7),num_layers=2,batch_first=True,bias=True).cuda()self.relu = nn.ReLU()def forward(self,dec_input,enc_hidden,enc_h_m):out, layer_h_c, last_h_m, _ = self.pred1_dec(dec_input,enc_hidden,enc_h_m)out = self.relu(out)return out, layer_h_c, last_h_m
enc=PredRNN_enc().cuda()
dec=PredRNN_dec().cuda()import itertools
loss_fn=nn.MSELoss()
position=0
optimizer=optim.Adam(itertools.chain(enc.parameters(), dec.parameters()),lr=0.001)
for epoch in range(1000):loss_total=0enc_hidden, enc_h_m = enc(input)for i in range(input.shape[1]):optimizer.zero_grad()out, layer_h_c, last_h_m = dec(input[:,i:i+1,:,:,:], enc_hidden, enc_h_m[-1])loss=loss_fn(out, target[:,i:i+1,:,:,:])loss_total+=lossenc_hidden = layer_h_cenc_h_m = last_h_mloss_total=loss_total/input.shape[1]loss_total.backward()optimizer.step()print(epoch,epoch,loss_total)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/788393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Docker】搭建便捷的Docker容器管理工具 - dockerCopilot

【Docker】搭建便捷的Docker容器管理工具 - dockerCopilot 前言 本教程基于绿联的NAS设备DX4600 Pro的docker功能进行搭建。前面有介绍过OneKey,而dockerCopilot便是OneKey的升级版,作者对其进行了重新命名,并且对界和功能都进行了全面的优…

负载均衡集群

一、集群的基本原理 集群:数据内容是一致的,集群可以被替代 分布式:各司其职,每台服务器存储自己独有的数据,对外作为单点被访问是访问整体的数据; 分布式是不能被替代的;分布式分为MFS、GFS、…

结构体内存对齐和位段(重点)!!!

乐观学习,乐观生活,才能不断前进啊!!! 我的主页:optimistic_chen 我的专栏:c语言 点击主页:optimistic_chen和专栏:c语言, 创作不易,大佬们点赞鼓…

数据结构栈和堆列

目录 栈: 栈的概念: 栈的实现: 栈接口的实现: 1.初始化栈: 2.入栈: 3.出栈: 4. 获取栈顶元素: 5.获取栈中有效数据的个数: 6.检测栈是否为空,如果为…

谈谈SSH整合--一起学习吧之系统架构

SSH整合是一种非常实用的Web应用程序开发框架,能够大大提高开发效率和应用程序的质量。 一、定义 SSH整合是指将Spring、Hibernate和Struts2这三个框架进行集成,形成一个统一的Web应用程序开发框架。这种整合可以大大提高开发效率和应用程序的稳定性。…

【备忘录】docker-maven-plugin 使用

在使用docker-maven-plugin 插件时,经常会碰到一些奇怪的问题: 比如: 1、docker远程访问时,认证安全问题? 2、dockerHost 访问地址准确性? 3、需要多个tag时如何处理? 4、push 到仓库时&#xf…

Java代码示例:演示多态特性及子类方法重写(day17)

java代码里面体现多态的特点: 第一步创建一个父类father, 然后创建子类subclasses, 最后创建一个DemoMulti, 上面的父类特有的方法不是私有的,因此子类能够继承。 新建一个父类方法Father 创建子类subclasses 在下面的代码中…

LabVIEW深度学习

目录 一、配置环境1.1、显卡选择1.2、下载显卡驱动1.3、下载并安装Anaconda1.4、配置Anaconda软件包下载服务器1.5、配置虚拟环境tf_gpu1.6、安装vscode1.7、安装tensorflow1.8、下载安装Git1.9、安装TensorFlow Object Detection API框架1.10、安装依赖的python软件包1.11、配…

Python 简单使用 RabbitMQ

一、安装 pip install pika 二、推送消息到队列中 执行pythone方法 import pika import time# 用户名和密码 user_info pika.PlainCredentials(admin,admin)# 连接服务器上的rabbitMQ服务 connection pika.BlockingConnection(pika.ConnectionParameters(127.0.0.1, 5672,…

HTTPS、对称/非对称加密、SSL/TLS

问题描述:HTTP的请求和响应都是明文传输,有安全隐患 HTTPS:HTTPS并不是一个单独的协议,是在 TCP 和 HTTP 之间加入了 SSL/TLS 安全协议,使得报文能够加密传输,SSL是TLS的前身,现在使用的大多都…

Taro活动列表中,对某一个活动添加分享按钮

采用data-留下分享链接的拼接参数 1.在item文件中写按钮 openType“share” <ButtonclassName{classes.rowRightShareButton}openType"share"data-share-transfer-id{lastGiftingTransferId}data-share-picture-url{shareUrl}data-share-title{shareTitle}onClic…

【Node】使用Node.js构建简单的静态页面生成器

使用Node.js构建简单的静态页面生成器 在现代的Web开发中&#xff0c;静态网站因其速度快、安全性高而越来越受到开发者的青睐。本文将介绍如何使用Node.js构建一个简单的静态页面生成器&#xff0c;通过这个小项目&#xff0c;你将了解到静态网站生成的基本原理和实现方法。 …

在开源的基础上构建 AI 需要一种全新的应用程序安全方法

人工智能已经从科幻小说中涌现出来&#xff0c;进入了我们的日常生活。 在开源软件&#xff08;OSS&#xff09;模型的支持下&#xff0c;人工智能革命正在加速。这些模型是专为开发 AI 而制作的复杂开源代码包&#xff0c;使组织能够高效、大规模地部署 AI 模型。 虽然大多数…

LLM 的下一站 Mamba,取代 Transformer,虽然在争议

虽然业界大佬对Mamba有点争议&#xff0c;但是直觉而言&#xff0c;Mamba会取代 Transformer 成为LLM的基础模型算法。 1&#xff0c; Mamba 比 Transformer的优点 1.1 处理的序列更长 1.2 比Transformer 更快 1.3 可解释性、可理解性、可控性、可调试性比 Transformer 更强 2…

StreamingT2V文本生成视频多模态大模型,即将开源!

1、前言 Picsart人工智能研究所、德克萨斯大学和SHI实验室的研究人员联合推出了StreamingT2V视频模型。通过文本就能直接生成2分钟、1分钟等不同时间&#xff0c;动作一致、连贯、没有卡顿的高质量视频。 虽然StreamingT2V在视频质量、多元化等还无法与Sora媲美&#xff0c;但…

npm配置项管理

全局模块路径配置 修改配置项 在使用Windows系统时&#xff0c;C盘告急一直被大家所诟病的问题&#xff0c;而nodejs的包管理工具npm默认将全局模块路径设置到了C盘。现要将npm全局模块路径设置到其他位置&#xff0c;减小C盘压力 npm config set prefix "E:\nodejs\no…

【C++第二阶段】文件操作

以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 文件操作文件写入流程简单的demo写操作 文件读流程二进制写文件二进制读文件 文件操作 文件写入流程 写文件包括以下几个步骤 1.包含头文件 2.创建流对象 3.打开文件&#xff0…

大数据学习第十二天(hadoop概念)

1、服务器之间数据文件传递 1&#xff09;服务器之间传递数据&#xff0c;依赖ssh协议 2&#xff09;http协议是web网站之间的通讯协议&#xff0c;用户可已通过http网址访问到对应网站数据 3&#xff09;ssh协议是服务器之间&#xff0c;或windos和服务器之间传递的数据的协议…

IP SSL的应用与安装

IP SSL&#xff0c;即互联网协议安全套接字层&#xff0c;它是一种为网络通信提供安全及数据完整性的安全协议。在网络传输过程中&#xff0c;IP SSL可以对数据进行加密&#xff0c;这样即便数据在传输途中被截取&#xff0c;没有相应的解密密钥也无法解读内容。这一过程如同将…

合并两个单链表

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 但行前路&#xff0c;不负韶华&#…