乳腺癌分类模型

news2024/11/17 17:35:50

乳腺癌分类模型的定义中,必须有_init_(初始化)函数和forward(正向传播)函数

乳腺癌分类模型定义

# 自定义模型
class MyModel(torch.nn.Module):
 	def __init__(self,in_features):
 		super(MyModel,self).__init__() #调用父类的构造函数!
 		# 搭建自己的神经网络
 		# 1.构建线性层
         #该层接受具有in_features数量的输入特征,并产生一个具有单个输出特征的结果
 		self.linear = torch.nn.Linear(in_features,1)
 		# 2.构建激活函数层
 		self.sigmoid = torch.nn.Sigmoid()
 	def forward(self,x):
 		"""重写了父类的 forward 函数,正向传播"""
		pred = self.linear(x)
 		out = self.sigmoid(pred)
 		return out

神经网络定义完成后:

①确定损失函数,学习率

②构建神经网络模型对象

构建优化器对象,并为优化器指定模型参数和学习率

# 二分类的交叉熵损失公式
loss = troch.nn.BCELoss()

# 学习率、迭代次数
learning_rate = 0.1
num_epochs = 100

# 获取样本量和特征数,创建模型
n_samples,n_features = X.shape
model = MyModle(n_features)

# 创建优化器
optimizer = torch.optim.SGD(model.parameters(),lr=learning_rate)

# 打印模型、打印模型参数
print(model)
print(list(model.parameters()))

模型参数集合中包括了两个子集,分别对应线性层self.linear当中的30个w和1个b

训练模型的参数

threshold_value = 0.00001
for epoch in range(num_epochs):
	y_pred = model(X_train) # 正向传播,调用 forward()方法
 	ls = loss(y_pred,Y_train) # 计算损失(标量值)
 	ls.backward() # 反向传播
 	optimizer.step() # 更新权重
 	optimizer.zero_grad() # 清空梯度
 	if epoch%5 == 0:
 		print(f"epoch:{epoch},loss={ls.item():.4f}")
 	if ls.item() <= threshold_value:
 		break;
print("模型训练完成! loss={}".format(ls))

计算模型预测的准确率

with torch.no_grad(): # 无需向后传播(非训练过程)
 	y_pred = model(X_test)
	# 上面计算出来的结果是 0-1 之间的数,将数据进行四舍五入,得到 0 或 1
 	y_pred_cls = y_pred.round()
 	# 统计结果
    # 如果相同,则为True,返回值为1;否则返回值为0,sum则是对该值相加
 	acc = y_pred_cls.eq(Y_test).sum().numpy()
 							/ float(Y_test.shape[0])
 	print(f"准确率:{acc.item():.4f}")

模型训练的数据分批

由于计算本身以及显存容量的限制,不可能一次性将所有数据全部加载到内存中进行计算,需要将训练集分批,把训练集合中的数据随机分成等量的几份,按批次迭代训练。

​ pytorch提供了torch.utils.data.DataLoader加载器,该加载器可以自动地将输入的数据进行打乱和分批。

DataLoader()的加载参数

  • dataset: 需要打乱的数据集

  • batch_size: 每一批数据条数量

  • shuffle: True或者False,表示是否将数据打乱后再分批

 如果要使用pytorch中的DataLoader,则需要

​         ①创建一个继承dataset类的子类对象

​                 因为DataLoader只能处理继承了Dataset类的子类对象

​         ②创建一个dataloader对象

​         ③迭代dataloader对象,通过其将data,label批量传入模型

数据的归一化处理

 transform=torchvision.transforms.ToTensor() 是PyTorch和torchvision库中的一个常见语法,用于图像预处理。具体来说,torchvision.transforms.ToTensor() 是一个函数,它接受一个PIL图像或NumPy ndarray,并返回一个PyTorch张量(Tensor)。这个函数的主要作用是将图像的像素值从0-255的整数范围转换为0-1的浮点数范围。

import numpy as np
# 用于绘图的库
import matplotlib.pyplot as plt

features,label = train_dataset[0]
print("第一个数据对应的标签名称:",label)
print(features.shape,label)
# 原始数据是归一化后的数据,因此这里需要反归一化
img = np.array(features)*255
img = img.reshape(28,28)

# 使用matplotlib的imshow函数来显示灰度图像
plt.imshow(img,"gray")
plt.show()

多分类问题

Softmax函数

​ 在多分类问题中,我们需要分类器输出每种分类的概率,并且概率之和为1.因此,将模型对不同分类的预测值映射为0-1之间的实数,并且通过归一化保证和为1.

神经网络用于多分类问题时,会将输出的最后一层,加上Softmax函数,用于数据的归一化输出

import numpy as np
def softmax(x):
    return np.exp(x)/np.sum(np.exp(x))

x = np.array([2.0,1.0,0.1])
outputs = softmax(x)

print(x)
print(outputs)
print(outputs.sum())

 损失函数

        代价函数也称为损失函数,反映的是预测结果和实际结果之间的差距,衡量当前预测结果的可用性和准确性。交叉熵是信息论领域的一种度量方法,它建立在熵的基础上,通常计算两种概率分布之间的差异。交叉熵是用来描述两个分布的距离的,神经网络训练的目的就是使预测结果的分布逼近真实的分布。

二分类交叉熵

在二分类的情况下,模型最终预测的结果概率为p和1-p,此时二分类交叉熵为

其中,y表示样本标签,正样本标签为1,负样本标签为0;p表示预测为正样本的概率

通过 torch.nn.BCELoss 计算二分类交叉熵

from torch import nn
loss = nn.BCELoss()
# 假设两个模型最后的预测结果相同,但是概率不同
model_one_pred = torch.tensor([0.9, 0.1])
model_two_pred = torch.tensor([0.6, 0.4])

#真实结果
target = torch.FloatTensor([1, 0])

#计算两种模型的损失
l1 = loss(model_one_pred, target)
l2 = loss(model_two_pred, target)
print(l1, l2)

 多分类交叉熵

J = -\sum_{i=1}^{K}y_{i}log(p_{i})

其中,K是种类数量,y是标签(如果类别是i,则等于1;否则等于0);p是神经网络的输出,也就是类别是i的概率,这个输出值由softmax计算得来的值

pytorch中,通过torch.nn.CrossEntropyLoss计算多分类交叉熵

loss = torch.nn.CrossEntropyLoss()
Y = torch.tensor([2,1,0])
 
model1_pred = torch.tensor(
 [[0.3, 0.3, 0.4], # predict class 2, right(weak)
 [0.3, 0.4, 0.3], # predict class 1, right(weak)
 [0.1, 0.2, 0.7]] # preiict class 2, Wrong(badly)
)
model2_pred = torch.tensor(
 [[0.1, 0.2, 0.7], # predict class 2, right(strong)
 [0.1, 0.7, 0.2], # predict class 1, right(strong)
 [0.4, 0.3, 0.3]]) # predict class 0, right(weak)

ls1 = loss(model1_pred,Y)
ls2 = loss(model2_pred,Y)
print(ls1, ls2)

 激活函数

Sigmoid函数

  
import numpy as np
# Matplotlib是Python中用于绘制图表和图形的库
import matplotlib.pyplot as plt

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# -10到10之间取100个数
x = np.linspace(-10, 10 ,100)
plt.plot(x, sigmoid(x), 'b')
# 在图上添加网格线,并设置网格线的样式为虚线
plt.grid(linestyle='--')
plt.show()

Tanh函数

def tanh(x):
    return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))

x = np.linspace(-10, 10 ,100)
plt.plot(x, tanh(x), 'b')

 ReLU激活函数

f(x)={0.........x<0\brace x......x>=0}

import numpy as np
import matplotlib.pyplot as plt
import torch

def relu(x): 
    return np.where(x >= 0, x, 0)
  
x = np.linspace(-10, 10, 1000)
y = relu(x)
plt.plot(x, y, 'b')
plt.grid(linestyle='--')
plt.show()

        神经网络是由多个神经元(线性函数)组成,从宽度上拓展神经元的数量,从深度上拓展而增加多层时,如果没有激活函数,整个神经网络仍然是一个线性模型(可推导),也就无法解决非线性问题。

多层神经网络的建立

在利用 PyTorch 建立神经网络模型时,需要注意以下几点:

  • 自定义的神经网络模型必须继承 nn.Module

  • 自定义的类中需要实现:

    • init: 定义网络的结构

    • forward: 定义数据在模型中的正向传播路径

import torch 
# 神经网络的建立
class NeuralNet(torch.nn.Module):
    def __init__(self,input_size,hidden_size,out_size):
        super(NeuralNet, self).__init__()
        self.linear1 = torch.nn.Linear(
            input_size,hidden_size
        )
        self.relu = torch.nn.ReLU()
        self.linear2 = torch.nn.Linear(hidden_size,out_size)
        # 二分类使用Sigmoid()函数,多分类使用Softmax()函数
        self.relu = torch.nn.Sigmoid()

    def forward(self,x):
        out = self.linear1(x)
        out = self.relu(out)
        out = self.linear2(out)
        out = self.sigmoid(out)
        return out

 hidden_size通常要比input_size大一倍

保存数据和训练数据

train_test_ptFile = './pt/train_test_pt_for_MNIST.pt'
torch.save((train_dataset, test_dataset),train_test_ptFile)

 使用PyTorch库将两个数据集(train_datasettest_dataset)保存到一个单一的.pt文件中。这是一种常见的做法,用于保存训练数据和测试数据,以便在之后可以轻松地加载它们,而无需重新加载或重新处理原始数据

import torch

train_test_ptFile = './pt/train_test_pt_for_MNIST.pt'
train_dataset, test_dataset = torch.load(train_test_ptFile)

创建数据加载器

from torch.utils.data import DataLoader
train_dataLoader = DataLoader(
    dataset=train_dataset,
    # 每次迭代过程中,模型接收100个样本进行训练
    batch_size=100,
    shuffle=True
)
test_dataLoader = DataLoader(
    dataset=test_dataset,
    batch_size=100,
    shuffle=True
)

创建神经网络模型

class HWR_Model(torch.nn.Module):
    def __init__(self,in_features, hidden_size, out_classes):
        super(HWR_Model,self).__init__()
        self.linear1 = torch.nn.Linear(in_features, hidden_size)
        self.relu = torch.nn.ReLU()
        self.linear2 = torch.nn.Linear(hidden_size, out_classes)
        self.Softmax = torch.nn.Softmax(dim=1)
        
    def forward(self,x):
        out = self.linear1(x)
        out = self.relu(out)
        out = self.linear2(out)
        out = self.Softmax(out)
        return out

model = HWR_Model(28*28, 500, 10).to(device)
lossF = torch.nn.CrossEntropyLoss()
# 自适应学习率,适合处理大规模数据和参数
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

神经网络模型训练

在神经网络训练过程中,我们通常使用梯度下降或其变种(如Adam、RMSprop等)来更新网络的权重。这些更新是基于损失函数(或目标函数)对权重的梯度。

具体来说,训练过程通常涉及以下步骤:

  1. 前向传播:输入数据通过网络生成输出。

  2. 计算损失:根据网络的输出和实际标签计算损失。

  3. 反向传播:计算损失对网络中每个权重的梯度。

  4. 权重更新:使用优化器(optimizer)和计算出的梯度来更新权重。

for epoch in range(5):
    # enumerate函数会返回每个批次的索引(i)和该批次的数据(features, labels)
    for i,(features, labels) in enumerate(train_dataLoader):
        # view 方法用于改变一个张量(tensor)的形状(shape)而不改变其数据
        features = features.view(-1, 28*28).to(device)
        labels = labels.to(device)

        pred = model(features)
        ls = lossF(pred, labels)
        ls.backward()
        
        # 使用在之前的反向传播步骤中计算出的梯度来更新网络的权重并清除这些梯度,以便下一次迭代
        optimizer.step()
        optimizer.zero_grad()

        if i % 100 ==0:
            print(f'loss={ls:.8f}')
    	break
	break

 迭代访问测试数据集

# 通过迭代来逐个访问数据集中的数据
sample = iter(test_dataLoader)

# next()函数会返回批次中的数据和标签
# 这段代码的作用是从test_dataLoader中获取一个批次的样本数据和标签,并将它们分别存储在features和labels变量
features, labels = next(sample)

创建图像

 

import matplotlib.pyplot as plt
for i in range(5):
    # 在一个图形窗口中创建一个 1 行 5 列的子图布局,并选择第 i+1 个子图进行操作(即绘制数据或图像)
    # 在一个窗口中绘制多个子图,每个子图显示不同的数据或图像
    plt.subplot(1, 5 , i+1)
    # 将 features 数组中的第 i 个样本的第 0 个通道的图像数据以灰度模式显示出来
    # 在一个窗口中绘制多个子图,每个子图显示不同的数据或图像
    plt.imshow(features[i][0], cmap='gray')


# 接下来的代码无需计算梯度
with torch.no_grad():
    pred = model(features)
    print(pred[:5].int())

# 在一个指定的轴上找到张量的最大值。axis=1意味着我们在每一行(即,对于每一个样本)上寻找最大值。对于二维张量,axis=0会沿着列方向(垂直方向)寻找最大值,
# 而axis=1会沿着行方向(水平方向)寻找最大值
# 只获取第二个值,即最大值的索引;第一个为占位符,应该返回的是最大值
_ , indeces = torch.max(pred[:5], axis=1)
print('预测值为:',indeces)
print('真实值为:',labels[:5])

模型准确率

with torch.no_grad():
    num_corrects = 0
    num_samples = 0
    for features, labels in test_dataLoader:
        features = features.view(-1, 28*28)
        pred = model(features)
        _, indeces = torch.max(pred, axis=1)
        num_corrects += (indeces == labels).sum().item()
        num_samples += len(labels)
        # break
    print(f'模型的准确率是:{num_corrects/num_samples:.2%}')

保存并加载模型

# 保存模型
model_state_ptFile = './model/hand_writing_model_states.pt'
torch.save(model.state_dict(), model_state_ptFile)


# 读取和装载模型参数
state_dict = torch.load(model_state_ptFile)
model = HWR_Model(28 * 28, hidden_size, 10)
model.load_state_dict(state_dict=state_dict)

CSV文件

 *.CSV(Comma-Separated Values)文件由任意数目的记录组成,每条记录由字段组成,字段间以‘逗号’或‘制表符’分隔。该文件以纯文本形式存在,通常用于存储表格数据(数字和文本)

import pandas as pd

 

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

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

相关文章

qt+ffmpeg 实现音视频播放(三)之视频播放

一、视频播放流程 &#xff08;PS&#xff1a;视频的播放流程跟音频的及其相似&#xff01;&#xff01;&#xff09; 1、打开视频文件 通过 avformat_open_input() 打开媒体文件并分配和初始化 AVFormatContext 结构体。 函数原型如下&#xff1a; int avformat_open_inpu…

Flask python 开发篇:链接mysql

一、历史回顾 根据上一篇&#xff1a;配置文件编写&#xff0c;已经把各种配置根据开发环境做了区分&#xff0c;再config.py中&#xff0c;我们可以分别处理测试、生产的相关配置&#xff0c;这节主要说一下数据库的链接和使用 二、配置数据库连接 Flask定义和链接数据库文…

手机可以格式化存储卡吗?格式化以后出现什么情况

随着智能手机的普及&#xff0c;存储卡&#xff08;如SD卡、MicroSD卡等&#xff09;已成为手机存储扩展的重要工具。然而&#xff0c;在使用过程中&#xff0c;我们有时可能会遇到需要格式化存储卡的情况。那么&#xff0c;手机能否直接格式化存储卡呢&#xff1f;格式化后存储…

【Flutter学习笔记】10.3 组合实例:TurnBox

参考资料&#xff1a;《Flutter实战第二版》 10.3 组合实例&#xff1a;TurnBox 这里尝试实现一个更为复杂的例子&#xff0c;其能够旋转子组件。Flutter中的RotatedBox可以旋转子组件&#xff0c;但是它有两个缺点&#xff1a; 一是只能将其子节点以90度的倍数旋转二是当旋转…

在服务器(Ubuntu20.04)安装用户级别的cuda11.8(以及仿照前面教程安装cuda11.3后安装cudnn和pytorch1.9.0)

1、cuda11.8的下载 首先在cuda官网下载我们需要的cuda版本&#xff0c;这里我下载的是cuda11.8&#xff08;我的最高支持cuda12.0&#xff09; 这里我直接使用wget命令下载不了&#xff0c;于是我直接在浏览器输入后面的链接下载到本地&#xff0c;之后再上传至服务器的&am…

数据分析概述、Conda环境搭建及JupyterLab的搭建

1. 数据分析职责概述 当今世界对信息技术的依赖程度在不断加深&#xff0c;每天都会有大量的数据产生&#xff0c;我们经常会感到数据越来越多&#xff0c;但是要从中发现有价值的信息却越来越难。这里所说的信息&#xff0c;可以理解为对数据集处理之后的结果&#xff0c;是从…

SQLiteC/C++接口详细介绍sqlite3_stmt类(十)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;九&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十一&#xff09; 38、sqlite3_column_value sqlite3_column_valu…

Python:熟悉简单的skfuzzy构建接近生活事件的模糊控制器”(附带详细注释说明)+ 测试结果

参考资料&#xff1a;https: // blog.csdn.net / shelgi / article / details / 126908418 ————通过下面这个例子&#xff0c;终于能理解一点模糊理论的应用了&#xff0c;感谢原作。 熟悉简单的skfuzzy构建接近生活事件的模糊控制器 假设下面这样的场景, 我们希望构建一套…

linux系统------------MySQL 存储引擎

目录 一、存储引擎概念介绍 二、常用的存储引擎 2.1MyISAM 2.1.1MYlSAM的特点 2.1.2MyISAM 表支持 3 种不同的存储格式⭐&#xff1a; &#xff08;1&#xff09;静态(固定长度)表 &#xff08;2&#xff09;动态表 &#xff08;3&#xff09;压缩表 2.1.3MyISAM适…

基于python+vue食品安全信息管理系统flask-django-nodejs-php

食品安全信息管理系统设计的目的是为用户提供食品信息、科普专栏、食品检测、检测结果、交流论坛等方面的平台。 与PC端应用程序相比&#xff0c;食品安全信息管理系统的设计主要面向于用户&#xff0c;旨在为管理员和用户提供一个食品安全信息管理系统。用户可以通过APP及时查…

Gitlab介绍

1.什么是Gitlab GitLab是一个流行的版本控制系统平台&#xff0c;主要用于代码托管、测试和部署。 GitLab是基于Git的一个开源项目&#xff0c;它提供了一个用于仓库管理的Web服务。GitLab使用Ruby on Rails构建&#xff0c;并提供了诸如wiki和issue跟踪等功能。它允许用户通…

欧科云链:2024将聚焦发展与安全,用技术助力链上数据安全和合规

近期&#xff0c;OpenAI和Web3.0两大新技术发展势头迅猛。OpenAI 再次引领AI领域的新浪潮&#xff0c;推出了创新的文本转视频模型——Sora&#xff0c;Sora 可以创建长达60 秒的视频&#xff0c;包含高度详细的场景、複杂的摄像机运动以及情感丰富角色&#xff0c;再次将AI 的…

Django在日志中使用AdminEmailHandler发送邮件(同步),及celery异步发送日志邮件的实现

目录 一、使用AdminEmailHandler实现发送日志通知邮件 1&#xff0c;配置日志项 2&#xff0c;配置邮件项 3&#xff0c;在视图里使用日志 二、继承AdminEmailHandler使用celery实现异步发送邮件 1&#xff0c;安装配置celery 2&#xff0c;继承AdminEmailHandler类&…

python食品安全信息管理系统flask-django-nodejs-php

。 食品安全信息管理系统是在安卓操作系统下的应用平台。为防止出现兼容性及稳定性问题&#xff0c;编辑器选择的是Hbuildex&#xff0c;安卓APP与后台服务端之间的数据存储主要通过MySQL。用户在使用应用时产生的数据通过 python等语言传递给数据库。通过此方式促进食品安全信…

VMware 15 中 Ubuntu与windows 10共享文件夹设置

wmware 15.5.7中安装ubuntu 22.04 物理机为windows 10 1.选中ubuntu中想要共享的文件夹右击&#xff0c;点属性 2.在Local network share中勾选share this folder&#xff0c;第一次会提示你安装samba&#xff0c;安装即可 3.window10的资源管理器中使用 虚拟机计算机名即可…

无人机采集图像的相关知识

1.飞行任务规划 一般使用飞行任务规划软件进行飞行任务的设计&#xff0c;软件可以自动计算相机覆盖和图像重叠情况。比如ArduPilot (ArduPilot - Versatile, Trusted, Open) 和UgCS (http://www.ugcs.com)是两个飞行任务规划软件&#xff0c;可以适用大多数无人机系统。 2.图…

如何减少pdf的文件大小?pdf压缩工具介绍

文件发不出去&#xff0c;有时就会耽误工作进度&#xff0c;文件太大无法发送&#xff0c;这应该是大家在发送PDF时&#xff0c;常常会碰到的问题吧&#xff0c;那么PDF文档压缩大小怎么做呢&#xff1f;因此我们需要对pdf压缩后再发送&#xff0c;那么有没有好用的pdf压缩工具…

解决IE11报错:CSS 因 Mime 类型不匹配而被忽略

简要概述&#xff1a; 本人用springboot开发网站&#xff0c;手动处理js和css文件请求&#xff0c;报错&#xff1a;CSS 因 Mime 类型不匹配而被忽略 后台代码&#xff1a; 如下三个代码块 GetMapping("/Guest/ASN1/{FileName}")public void GetFiles(PathVariab…

阿里云 EMR Serverless Spark 版免费邀测中

随着大数据应用的广泛推广&#xff0c;企业对于数据处理的需求日益增长。为了进一步优化大数据开发流程&#xff0c;减少企业的运维成本&#xff0c;并提升数据处理的灵活性和效率&#xff0c;阿里云开源大数据平台 E-MapReduce &#xff08;简称“EMR”&#xff09;正式推出 E…

SQL中条件放在on后与where后的区别

数据库在通过连接两张或多张表来返回记录时&#xff0c;都会生成一张中间的临时表&#xff0c;然后再将这张临时表返回给用户。 在使用left jion时&#xff0c;on和where条件的区别如下&#xff1a; on条件是在生成临时表时使用的条件&#xff0c;不管on中的条件是否为真&…