搭建PyTorch神经网络进行气温预测(手写+调包两种方法)(保证学会!)+找到神经网络的最优情况

news2024/11/30 14:48:55

代码上有注释!!!!!!

本篇主要包括三大部分:

第一部分:导入数据集+导入第三方库+数据集简单介绍与可视化+数据集简单预处理

第二部分:手写神经网络代码实现气温预测(手写)

第三部分:调包搭建神经网络实现气温预测(调包)+找到最优网络模型及其参数

​​​​​​​

目录

第一部分  准备数据

(一)导入第三方库

(二) 导入数据集

(三)数据可视化

​编辑

 (四)独热编码处理

 (五)数据标准化

第二部分 人工手写神经网络 

(一)将数据转换成tensor形式

 (二)权重、偏置初始化

(三)设置学习率

(四) 训练网络

第三部分 调包实现神经网络预测气温

(一)设置参数

(二)调用torch.nn中的Sequential序列模块

 (三)损失函数

(四)优化器

(五)训练网络

(六)预测结果

 (七)预测结果和真实标签进行可视化对比

 (八)找到最优模型及其参数


第一部分  准备数据

(一)导入第三方库

import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt
import torch
import torch.optim as optim
import warnings
warnings.filterwarnings("ignore")
%matplotlib inline

①import warnings 和  warnings.filterwarnings("ignore"):

导入Python的warnings模块,用于处理警告信息。设置忽略警告信息,这样在后续运行代码时不会显示警告。主要是排除版本不同时的警告。


②%matplotlib inline:

这是Jupyter Notebook的魔术命令,用于在Notebook中显示matplotlib绘制的图形,而不是弹出新窗口显示图形。

(二) 导入数据集

features = pd.read_csv('temps.csv')

#看看数据长什么样子
features.head()

 前五行数据如下:

数据表中

  • year,moth,day,week分别表示的具体的时间
  • temp_2:前天的最高温度值
  • temp_1:昨天的最高温度值
  • average:在历史中,每年这一天的平均最高温度值
  • actual:这就是我们的标签值了,当天的真实最高温度
  • friend:这一列是凑热闹的,猜测的可能值,不用管这一列
print('数据维度:', features.shape)

说明数据中一共有348个样本,9个特征。

(三)数据可视化

# 处理时间数据
import datetime
# 分别得到年,月,日
years = features['year']
months = features['month']
days = features['day']

# datetime格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]
dates[:5]

打印一下dates[:5],查看前五行数据,结果如下:

两个零分别代表小时和分钟

# 准备画图
# 指定默认风格
plt.style.use('fivethirtyeight')

# 设置布局
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize = (10,10))
#subplots就是画子图2*2,((ax1, ax2), (ax3, ax4))分别是四个子图
fig.autofmt_xdate(rotation = 45)#x轴标签旋转度

# 标签值
ax1.plot(dates, features['actual'])#表示第一个子图里边x轴和y轴分别是什么
ax1.set_xlabel(''); ax1.set_ylabel('Temperature'); ax1.set_title('Max Temp')
#在这x轴没画值,因为和子图3是一样的y轴,y轴的名称是Temperature,图的名字是Max Temp

# 昨天
ax2.plot(dates, features['temp_1'])
ax2.set_xlabel(''); ax2.set_ylabel('Temperature'); ax2.set_title('Previous Max Temp')

# 前天
ax3.plot(dates, features['temp_2'])
ax3.set_xlabel('Date'); ax3.set_ylabel('Temperature'); ax3.set_title('Two Days Prior Max Temp')

#猜测的数值
ax4.plot(dates, features['friend'])
ax4.set_xlabel('Date'); ax4.set_ylabel('Temperature'); ax4.set_title('Friend Estimate')

plt.tight_layout(pad=2)#每个子图之间的间隔

结果如下:

 (四)独热编码处理

# 独热编码 one-hot
# features = pd.get_dummies(features)#帮你判断哪一列是字符串,自动地帮你把字符串直接展开
features = pd.get_dummies(features).astype(int)#输出打印体会一下加不加.astype(int)的区别
features.head(5)

前五行数据如下: 

# 标签
labels = np.array(features['actual'])

# 在特征中去掉标签
features= features.drop('actual', axis = 1)#把标签这一列踢出去

# 名字单独保存一下,以备后患
feature_list = list(features.columns)

# 转换成合适的格式
features = np.array(features)
features.shape

 

 (五)数据标准化

#标准化
from sklearn import preprocessing
#preprocessing预处理模块
input_features = preprocessing.StandardScaler().fit_transform(features)

 结果如下:

如上: 现在所有的值都是数组的结构,但torch要tensor的格式结构,所以下面要将数组形式转换成tensor的形式。

第二部分 人工手写神经网络 

(一)将数据转换成tensor形式

#把要用的数据转换成tensor的格式
x = torch.tensor(input_features, dtype = float)
y = torch.tensor(labels, dtype = float)

x就作为输入数据,是348*14的维度 

 (二)权重、偏置初始化

# 权重参数初始化
#w,b都是随机初始化
weights = torch.randn((14, 128), dtype = float, requires_grad = True) 
biases = torch.randn(128, dtype = float, requires_grad = True) 
weights2 = torch.randn((128, 1), dtype = float, requires_grad = True) 
biases2 = torch.randn(1, dtype = float, requires_grad = True) 

requires_grad = True:进行计算梯度

 在这里构建了两个隐藏层,权重w和偏置b都是进行的随机初始化

由于输入数据的维度是384*14

故第一个隐藏层的权重weights是14*128的矩阵,偏置biases长度为128

第二个隐藏层的权重weights2是128*1的行向量,偏置biases2长度为1

因为这里是做回归,也就是预测某一时刻的温度,最终输出的是一个值,故最终的权重weights的维度是128*1

 

这里补充一点:

输入数据x的维度是348*14,第一个隐藏层的权重weights维度为14*128,那么x*weights做矩阵运算后的结果维度是348*128,但是偏置biases的维度是torch.Size([128]),相当于可以看作是有128个元素的行向量,那么一个348*128的矩阵,怎么和一个1*128的行向量进行加法运算呢?

在这种情况下,PyTorch会自动将大小为 [128] 的张量 biases扩展为大小为 [348, 128] 的张量,使得两个张量的形状相匹配,然后再进行逐元素的加法运算。具体来说,PyTorch会将大小为 [128] 的行向量biases 在第二维上进行复制,扩展为大小为 [348, 128] 的矩阵,然后再与x*weights的结果进行逐元素相加。

(三)设置学习率

learning_rate = 0.001 

学习率是可以自己设置的

更新参数的话,我们要沿着一个方向进行参数更新,这个学习率就是告诉我们要沿着这个方向走多大的距离

一般来说,学习率要相对小一点,如果太大了,模型可能做的就相对没有那么好了

(四) 训练网络

losses = []#损失
#迭代更新1000次
for i in range(1000):
    # 计算隐层
    hidden = x.mm(weights) + biases
    #x.mm就是一个矩阵乘法  x*w+b
    
    #一般计算好隐藏层后,都要进行一个非线性映射
    #非线性映射里边也有很多函数,比如这里就用到了rule,小于0的时候都等于0,大于0的时候都等于x,y=x
    # 加入激活函数
    hidden = torch.relu(hidden)#得到实际隐藏层结果
    
    # 预测结果
    predictions = hidden.mm(weights2) + biases2
    #计算损失
    loss = torch.mean((predictions - y) ** 2) #计算的是均方误差
    #现在loss是tensor的格式,如果要画图的话,需要的是数组的格式
    losses.append(loss.data.numpy())
    
    # 打印损失值
    #每隔一百次打印一次损失
    if i % 100 == 0:
        print('loss:', loss)
    #返向传播计算
    loss.backward()
    
    #更新参数w,b
    #在这里这么理解一下,一会其实可以调包的
    weights.data.add_(- learning_rate * weights.grad.data)  #weights.grad.data取这一次反向传播的梯度值
    #沿着梯度的反方向进行更新,所以有这个-负号
    
    biases.data.add_(- learning_rate * biases.grad.data)
    weights2.data.add_(- learning_rate * weights2.grad.data)
    biases2.data.add_(- learning_rate * biases2.grad.data)
    
    # 每次迭代都得记得清空
    #每一次迭代都应该是独立的,和上一次没关系
    #torch如果没有清零,它会累加
    weights.grad.data.zero_()
    biases.grad.data.zero_()
    weights2.grad.data.zero_()
    biases2.grad.data.zero_()

 通过下边的结果,可以发现它的losse是随着迭代次数的增加不断降低的,最终趋于平稳。

 结果如下:

 下边是迭代结束后第一个隐藏层权重和偏置的参数,明显和初始随机初始化的参数不同,说明参数进行了梯度更新。

 注意:

循环结束后打印的参数值是最后一次迭代后的参数值,但不一定是最优参数值。要获取最优参数值,需要在训练过程中记录并比较每次迭代的性能,从而找到最佳的参数。

第三部分 调包实现神经网络预测气温

(一)设置参数

input_size = input_features.shape[1]#输入特征的个数  14个
hidden_size = 128#隐藏层 可以自己改
output_size = 1#输出值 一个
batch_size = 16

input_size表示输入特征的个数,这里是14个

hidden_size = 128:隐藏层有128个隐藏单元。

output_size = 1:这行代码定义了输出值的大小,即模型输出一个标量值。

batch_size:表示每个批次包含16个样本

(二)调用torch.nn中的Sequential序列模块

在调包环节中,和我们第二部分手写神经网络代码不同,权重参数、偏置参数是自动帮我们初始化的

#下边就是调包环节了
#torch.nn中的一个Sequential序列模块,就是按顺序,先执行第一个,再执行第二个,以此类推
#我定义的序列叫做my_nn
my_nn = torch.nn.Sequential(
    torch.nn.Linear(input_size, hidden_size),
    #全连接层,权重参数是自动帮我们初始化的
    torch.nn.Sigmoid(),#nn.ReLu()
    #激活函数
    torch.nn.Linear(hidden_size, output_size),
)

 (三)损失函数

cost = torch.nn.MSELoss(reduction='mean')#损失函数

 torch.nn.MSELoss:这是 PyTorch 中用于计算均方误差的类。
reduction='mean':这是 torch.nn.MSELoss 类的一个参数,用于指定损失的计算方式。
在这里,设置为 'mean' 表示计算所有样本的均方误差后再取平均值作为最终损失值

(四)优化器

optimizer = torch.optim.Adam(my_nn.parameters(), lr = 0.001)

Adam优化器效率高 效果好

my_nn.parameters()表示将神经网络模型my_nn的所有参数传递给优化器,以便优化这些参数。lr=0.001表示学习率为0.001,即Adam优化器在更新参数时所采用的学习率。

(五)训练网络

# 训练网络
losses = []
for i in range(1000):
    batch_loss = []
    # MINI-Batch方法来进行训练
    for start in range(0, len(input_features), batch_size):
        end = start + batch_size if start + batch_size < len(input_features) else len(input_features)
# 如果 start + batch_size 的结果小于 input_features 的长度(即 len(input_features)),则将 end 的值设为 start + batch_size。
# 否则,如果 start + batch_size 的结果大于或等于 input_features 的长度,那么 end 的值将设为 len(input_features)
        xx = torch.tensor(input_features[start:end], dtype = torch.float, requires_grad = True)
        yy = torch.tensor(labels[start:end], dtype = torch.float, requires_grad = True)
        prediction = my_nn(xx)
        loss = cost(prediction, yy)
        optimizer.zero_grad()#梯度清零
        loss.backward(retain_graph=True)#反向传播
        optimizer.step()#反向传播之后再进行参数更新
        batch_loss.append(loss.data.numpy())
        #print(len(batch_loss))#结果是22 len(input_features)=348  batch_size=16,21*16+12=348
    
    
    # 打印损失,每更新迭代一百次打印一次损失
    if i % 100==0:
        losses.append(np.mean(batch_loss))
#         print(losses)
        print(i, np.mean(batch_loss))

结果如下:

 

在这段代码中,通过迭代训练神经网络来降低损失函数值,使得神经网络的预测结果更接近真实标签。在每次迭代过程中,会计算一个 mini-batch 的损失值,并根据这个 mini-batch 更新神经网络的参数。
最终目的是通过不断迭代训练,使得损失函数值逐渐减小,达到一个较好的模型效果。


# 在代码中,损失值逐渐减小的原因可能有以下几点:

梯度下降优化算法:通过调用 optimizer.step() 方法,使用梯度下降算法来更新神经网络的参数,使得损失值逐渐减小。

学习率调整:在梯度下降算法中,学习率的设置对模型训练的效果有很大影响。合适的学习率能够使得模型更快地收敛到最优解。

迭代次数:在迭代次数足够多的情况下,模型有更多的机会逐渐优化参数,从而使得损失值逐渐减小。

Mini-batch 训练:使用 mini-batch 训练方法,可以更有效地利用计算资源,同时也有助于模型的收敛。

综合以上因素,随着迭代次数的增加,损失值逐渐减小是一个正常的训练过程。当损失值趋于稳定时,可以认为模型已经收敛到一个较好的状态。

(六)预测结果

x = torch.tensor(input_features, dtype = torch.float)
predict = my_nn(x).data.numpy() #每一个样本,也就是每一天的预测值

 预测结果如下:

 (七)预测结果和真实标签进行可视化对比

# 转换日期格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]

# 创建一个表格来存日期和其对应的标签数值
true_data = pd.DataFrame(data = {'date': dates, 'actual': labels})

# 同理,再创建一个来存日期和其对应的模型预测值
months = features[:, feature_list.index('month')]
days = features[:, feature_list.index('day')]
years = features[:, feature_list.index('year')]

test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]

test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates]

predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predict.reshape(-1)}) 

# 真实值
plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual')

# 预测值
plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction')
plt.xticks(rotation = 60)
plt.legend()#添加图例

# 图名
plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values');

结果如下:

 (八)找到最优模型及其参数

我们试想,上边预测出来的结果,是在最优参数模型情况下吗?其实并不是的,是在最后一次迭代结束后的参数基础上进行的预测。

下边我们一起学习一下寻找最优模型及其参数的过程。

# 训练网络
losses = []
# 初始化 best_loss 为一个很大的值,确保第一次比较不会出错
best_loss = float('inf')
import copy

for i in range(1000):
    batch_loss = []
    # MINI-Batch方法来进行训练
    for start in range(0, len(input_features), batch_size):
        end = start + batch_size if start + batch_size < len(input_features) else len(input_features)
# 如果 start + batch_size 的结果小于 input_features 的长度(即 len(input_features)),则将 end 的值设为 start + batch_size。
# 否则,如果 start + batch_size 的结果大于或等于 input_features 的长度,那么 end 的值将设为 len(input_features)
        xx = torch.tensor(input_features[start:end], dtype = torch.float, requires_grad = True)
        yy = torch.tensor(labels[start:end], dtype = torch.float, requires_grad = True)
        prediction = my_nn(xx)
        #print(prediction)
        loss = cost(prediction, yy)
        optimizer.zero_grad()#梯度清零
        loss.backward(retain_graph=True)#反向传播
        optimizer.step()#反向传播之后再进行参数更新
        batch_loss.append(loss.data.numpy())
        #print(len(batch_loss))#结果是22 len(input_features)=348  batch_size=16,21*16+12=348
    
    # 计算整体损失
    xx_val = torch.tensor(input_features, dtype=torch.float)
    yy_val = torch.tensor(labels, dtype=torch.float)
    prediction_val = my_nn(xx_val)
    loss_val = cost(prediction_val, yy_val)
    val_loss = loss_val.data.numpy()

    # 如果当前epoch的验证损失更低,则保存当前模型的权重
    if val_loss < best_loss:
        best_loss = val_loss
        best_model_weights = copy.deepcopy(my_nn.state_dict())
        
#     # 打印损失
#     if i % 100==0:
#         losses.append(np.mean(batch_loss))
# #         print(losses)
#         print(i, np.mean(batch_loss))

这里,我们在原先的代码上,做了一点小改动。

best_loss = float('inf'):表示最优损失,初始化 best_loss 为一个很大的值,确保第一次比较不会出错。

要得到最优情况下的模型,需要在训练过程中保存性能最好的模型权重。这可以通过在每次迭代结束时计算损失,并将其与之前的最佳损失进行比较来实现。如果当前迭代的损失更低,则保存当前模型的权重。

best_model_weights = copy.deepcopy(my_nn.state_dict()):执行这行代码,你可以保存当前神经网络模型的参数状态,以便在后续的训练过程中使用或恢复模型的状态。

最优参数如下:

<All keys matched successfully>的运行结果表示成功地将最佳模型的权重加载到了神经网络模型中。这意味着load_state_dict()方法成功地将最佳模型的权重参数与当前神经网络模型的相应参数进行匹配,并将最佳模型的权重参数加载到了当前模型中。

因此,<All keys matched successfully>的输出表明加载权重的过程顺利完成,当前模型已经成功地更新为最佳模型的状态,可以继续使用这个模型进行预测或其他任务。

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

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

相关文章

线性表概念及实现1

文章目录 前言一、线性表1.定义2.特点3.一般线性表的抽象数据类型定义 二、线性表的顺序存储&#xff08;顺序表&#xff09;1.基本概念2.数组实现顺序表3.顺序表中基本操作的具体实现 总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学习历程&#…

repl_backlog原理

2.2.3.repl_backlog原理 master怎么知道slave与自己的数据差异在哪里呢? 这就要说到全量同步时的repl_baklog文件了。 这个文件是一个固定大小的数组&#xff0c;只不过数组是环形&#xff0c;也就是说角标到达数组末尾后&#xff0c;会再次从0开始读写&#xff0c;这样数组…

Stack_经典例题_最小栈

题目&#xff1a; 题目分析&#xff1a; 在满足栈的特点的同时&#xff0c;还需要设计一个接口&#xff0c;就是获取栈内的最小元素&#xff01; 解题思路&#xff1a; 因为是栈&#xff0c;所以不好遍历的&#xff01;所以这题的方式不能采用遍历的方式&#xff0c;如果采取…

文心一言 VS 讯飞星火 VS chatgpt (234)-- 算法导论17.2 2题

二、用核算法重做练习17.1-3。练习17.1-3的内容是&#xff1a;假定我们对一个数据结构执行一个由 n 个操作组成的操作序列&#xff0c;当 i 严格为 2 的幂时第 i 个操作的代价为 i &#xff0c;否则代价为1。使用聚合分析确定每个操作的摊还代价。 文心一言&#xff1a; 练习…

国产HMI芯片Model3C ——工业品质价格亲民

工业级芯片相较于消费级芯片&#xff0c;在性能上确实拥有显著的优势&#xff0c;尤其对于带彩屏显示或HMI的产品来说&#xff0c;这种优势表现得尤为突出。 首先&#xff0c;对于带彩屏显示或HMI人机交互的产品来说&#xff0c;高性能的芯片是保证流畅的用户体验和快速响应的…

中颖51芯片学习5. 类EEPROM操作

中颖51芯片学习5. 类EEPROM操作 一、SH79F9476 Flash存储空间1. 特性2. 分区3. OP_EEPROMSIZE选项设置3. 编程接口4. 代码保护控制模式简介&#xff08;1&#xff09;**代码保护模式0&#xff1a;**&#xff08;2&#xff09;**代码保护模式1&#xff1a;**&#xff08;3&#…

VS2019 VS2022 LNK2019 无法解析的外部符号sprintf

解决方案&#xff1a; 项目属性》配置属性》链接接-》输入》附加依赖项&#xff0c;增加 legacy_stdio_definitions.lib legacy_stdio_definitions.lib 是一个库文件&#xff0c;通常与使用 Visual Studio 编译的 C/C 项目相关。它的作用是解决在使用新版本的 Visual Studio 编…

选以太网不选IB?AI网络构建未来趋势预测

据美国媒体Information报道&#xff0c;OpenAI和微软计划用千亿美金打造一款名为“Stargate”的超级计算机。 在选择网络方案时&#xff0c;即便微软是Infiniband的用户&#xff0c;OpenAI还是更加倾向使用以太网电缆而不是Infiniband电缆&#xff08;简称IB&#xff09;&…

LangChain-10(2) 加餐 编写Agent获取本地Docker运行情况 无技术含量只是思路

可以先查看 上一节内容&#xff0c;会对本节有更好的理解。 安装依赖 pip install langchainhub编写代码 核心代码 tool def get_docker_info(docker_name: str) -> str:"""Get information about a docker pod container info."""result…

Python 复杂密码图形化生成工具,支持选择生成10位和12位复杂密码(初版)

代码 #!/usr/bin/env python # -*- coding: utf-8 -*- # Time : 2024/3/26 15:22 # Author : wyq # File : 部署测试.py import random import string from tkinter import *def generate_password(length):characters string.ascii_letters string.digits string.p…

Java二叉树(2)

一、二叉树的链式存储 二叉树的存储分为顺序存储和链式存储 &#xff08;本文主要讲解链式存储&#xff09; 二叉树的链式存储是通过一个一个节点引用起来的&#xff0c;常见的表示方式有二叉三叉 // 孩子表示法 class Node { int val; // 数据域 Node left; // 左孩子的引用…

【网站项目】校园订餐小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

寻找可用API中的错误解决

目的&#xff1a;通过API调用大模型提取图像特征 百度 API 1.用百度的api调用llama时报错 Max retries exceeded with url&#xff0c;Caused by SSLError(SSLEOFError(8, EOF occurred in violation of protocol (_ssl.c:1131)))) 解决&#xff1a;试了关闭多余链接等方法…

信号完整性之哪来的串扰?

原文来自微信公众号&#xff1a;工程师看海&#xff0c;与我联系&#xff1a;chunhou0820 看海原创视频教程&#xff1a;《运放秘籍》 大家好&#xff0c;我是工程师看海。 我们经常听说PCB走线间距大于等于3倍线宽时可以抑制70%的信号间干扰&#xff0c;这就是3W原则&#…

大恒相机-程序异常退出后显示被占用

心跳时间代表多久向相机发送一次心跳包&#xff0c;如果超时则设备会认为断开了&#xff0c;停止工作并主动释放占用资源。 在相机打开后添加代码&#xff1a; #ifdef _DEBUG//设置心跳超时时间 3sObjFeatureControlPtr->GetIntFeature("GevHeartbeatTimeout")-&…

Spring Cloud学习笔记:Eureka简介,Eureka简单样例

这是本人学习的总结&#xff0c;主要学习资料如下 - 马士兵教育 [TOC](目录)1、Eureka 1.1、架构 Eureka是SpringCloud Nexflix的核心子模块&#xff0c;其中包含Server和Client。 Server提供服务注册&#xff0c;存储所有可用服务节点。 Client用于简化和Server的通讯复杂…

适用于W波段GaAs开关设计的可扩展p-i-n二极管建模与参数提取技术

来源&#xff1a;Scalable p-i-n Diode Modeling and Parameter Extraction for Use in the Design of W-Band GaAs Switch&#xff08;TIE 21年&#xff09; 摘要 本文介绍了一种针对W波段开关设计的基于毫米波GaAs的p-i-n二极管的可扩展建模与参数提取方法。采用基于晶圆上…

深入理解图形处理器(GPU):加速人工智能和大数据计算的引擎

文章目录 1. 什么是GPU&#xff1f;2. GPU的工作原理3. GPU的应用领域4. GPU与CPU的比较参考与推荐 前言&#xff1a; 图形处理器&#xff08;GPU&#xff09;不再仅仅是用于图形渲染的硬件设备。如今&#xff0c;GPU已经成为加速人工智能、大数据计算和科学研究的关键引擎。本…

基因查询常用汇总网(自备)

目录 NCBI genecards HPA数据库 gepia2 cbioporta kmplot生存分析 ualcan ​​​​​​​ 进行一些常用的基因功能蛋白及表达的网站查询汇总&#xff0c;方便个人使用 NCBI National Center for Biotechnology Information (nih.gov) 查询基因的曾用名和其他ID&…

【c语言】声明变量和初始化变量的区别

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…