首页 > 其他分享 >浅浅了解一下图像分割(pytorch框架)

浅浅了解一下图像分割(pytorch框架)

时间:2024-03-16 20:04:40浏览次数:20  
标签:__ ... nn img 浅浅 self pytorch 图像

1、图像分割是什么

         图像分割分类是对图像中属于特定类别的像素进行分类的过程,因此图像分割可以认为是按像素进行分类的问题。

        传统的图像分割算法均是基于灰度值的不连续和相似的性质。而基于深度学习的图像分割技术则是利用卷积神经网络,来理解图像中的每个像素所代表的真实世界物体,这在以前是难以想象的。

2、图像分割的类型有哪些?

基于深度学习的图像分割技术主要分为两类:语义分割实例分割

语义分割会为图像中的每个像素分配一个类别,但是同一类别之间的对象不会区分。

实例分割是将图像中的每个物体实例标记出来,并为每个实例生成一个像素级的分割掩码。

实例分割看起来与目标检测相似,不同的是目标检测输出目标的边界框和类别,实例分割输出的是目标的Mask和类别。

看一下下面的图就明白了。

3、分割网络是怎么搭建的?

图像分割网络的构建通常涉及以下几个步骤:

1. 选择网络架构:首先要选择适合您任务的网络架构。常用的图像分割网络包括 U-Net、FCN、DeepLab 等。这些网络具有不同的结构和特点,适用于不同的应用场景。

2. 构建编码器和解码器部分:图像分割网络通常包括编码器和解码器两部分。编码器负责从输入图像中提取特征,通常通过卷积神经网络(CNN)来实现。解码器负责将编码器提取的特征映射回原始图像尺寸的预测结果。编码器和解码器之间通常会有一些连接,用于跳跃连接或信息传递,例如 U-Net 中的跳跃连接结构。

3. 选择损失函数:图像分割任务通常会使用像素级别的标签进行训练,因此常用的损失函数包括交叉熵损失、Dice 损失等。这些损失函数可以帮助网络学习正确的像素分类。

4. 选择优化器:选择合适的优化器来优化网络参数,例如 SGD、Adam 等。优化器的选择可以影响网络的收敛速度和性能。

5. 数据准备和预处理:准备训练数据集,并进行必要的预处理操作,例如图像缩放、裁剪、归一化等。同时,也要准备相应的标签数据,确保标签与图像对应匹配。

6. 训练网络: 使用准备好的训练数据集对网络进行训练。在训练过程中,输入图像被提供给网络,通过反向传播算法更新网络参数,以最小化损失函数。

7. 模型评估和调优:使用验证集或测试集对训练好的模型进行评估,并根据评估结果对网络进行调优。常见的评估指标包括 IoU(Intersection over Union)、Dice 系数等。

8. 模型应用:在实际应用中使用训练好的模型对新的图像进行分割预测。

创建个简单的分类网络实战:

数据存放格式:

├─data
    ├─test
    │  ├─last
    │  └─last_msk
    └─train
        ├─last
        └─last_msk

展示:       train/last图片                                                      train/last_msk图片

                  

加载数据集代码:

from torch.utils.data import Dataset
import os
import cv2
import numpy as np


class MyDataset(Dataset):
    def __init__(self, train_path, transform=None):
        self.images = os.listdir(train_path + '/last')
        self.labels = os.listdir(train_path + '/last_msk')
        assert len(self.images) == len(self.labels), 'Number does not match'
        self.transform = transform
        self.images_and_labels = []    # 存储图像和标签路径
        for i in range(len(self.images)):
            self.images_and_labels.append((train_path + '/last/' + self.images[i], train_path + '/last_msk/' + self.labels[i]))

    def __getitem__(self, item):
        img_path, lab_path = self.images_and_labels[item]
        img = cv2.imread(img_path)
        img = cv2.resize(img, (224, 224))
        lab = cv2.imread(lab_path, 0)
        lab = cv2.resize(lab, (224, 224))
        lab = lab / 255    # 转换成0和1
        lab = lab.astype('uint8')    # 不为1的全置为0
        lab = np.eye(2)[lab]    # one-hot编码
        lab = np.array(list(map(lambda x: abs(x-1), lab))).astype('float32')   # 将所有0变为1(1对应255, 白色背景),所有1变为0(黑色,目标)
        lab = lab.transpose(2, 0, 1)  # [224, 224, 2] => [2, 224, 224]
        if self.transform is not None:
            img = self.transform(img)
        return img, lab

    def __len__(self):
        return len(self.images)


if __name__ == '__main__':
    img = cv2.imread('data/train/last_msk/150.jpg', 0)
    img = cv2.resize(img, (16, 16))
    img2 = img/255
    img3 = img2.astype('uint8')
    hot1 = np.eye(2)[img3]
    hot2 = np.array(list(map(lambda x: abs(x-1), hot1)))
    print(hot2.shape)
    print(hot2.transpose(2, 0, 1))

模型代码:

import torch
from torch import nn


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.encode1 = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(True),
            nn.MaxPool2d(2, 2)
        )
        self.encode2 = nn.Sequential(
            nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(True),
            nn.MaxPool2d(2, 2)
        )
        self.encode3 = nn.Sequential(
            nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(True),
            nn.Conv2d(256, 256, 3, 1, 1),
            nn.BatchNorm2d(256),
            nn.ReLU(True),
            nn.MaxPool2d(2, 2)
        )
        self.encode4 = nn.Sequential(
            nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(True),
            nn.Conv2d(512, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(True),
            nn.MaxPool2d(2, 2)
        )
        self.encode5 = nn.Sequential(
            nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(True),
            nn.Conv2d(512, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(True),
            nn.MaxPool2d(2, 2)
        )
        self.decode1 = nn.Sequential(
            nn.ConvTranspose2d(in_channels=512, out_channels=256, kernel_size=3,
                               stride=2, padding=1, output_padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(True)
        )
        self.decode2 = nn.Sequential(
            nn.ConvTranspose2d(256, 128, 3, 2, 1, 1),
            nn.BatchNorm2d(128),
            nn.ReLU(True)
        )
        self.decode3 = nn.Sequential(
            nn.ConvTranspose2d(128, 64, 3, 2, 1, 1),
            nn.BatchNorm2d(64),
            nn.ReLU(True)
        )
        self.decode4 = nn.Sequential(
            nn.ConvTranspose2d(64, 32, 3, 2, 1, 1),
            nn.BatchNorm2d(32),
            nn.ReLU(True)
        )
        self.decode5 = nn.Sequential(
            nn.ConvTranspose2d(32, 16, 3, 2, 1, 1),
            nn.BatchNorm2d(16),
            nn.ReLU(True)
        )
        self.classifier = nn.Conv2d(16, 2, kernel_size=1)

    def forward(self, x):           # b: batch_size
        out = self.encode1(x)       # [b, 3, 224, 224]  =>  [b, 64, 112, 112]
        out = self.encode2(out)     # [b, 64, 112, 112] =>  [b, 128, 56, 56]
        out = self.encode3(out)     # [b, 128, 56, 56]  =>  [b, 256, 28, 28]
        out = self.encode4(out)     # [b, 256, 28, 28]  =>  [b, 512, 14, 14]
        out = self.encode5(out)     # [b, 512, 14, 14]  =>  [b, 512, 7, 7]
        out = self.decode1(out)     # [b, 512, 7, 7]    =>  [b, 256, 14, 14]
        out = self.decode2(out)     # [b, 256, 14, 14]  =>  [b, 128, 28, 28]
        out = self.decode3(out)     # [b, 128, 28, 28]  =>  [b, 64, 56, 56]
        out = self.decode4(out)     # [b, 64, 56, 56]   =>  [b, 32, 112, 112]
        out = self.decode5(out)     # [b, 32, 112, 112] =>  [b, 16, 224, 224]
        out = self.classifier(out)  # [b, 16, 224, 224] =>  [b, 2, 224, 224]   2表示类别数,目标和非目标两类
        return out


if __name__ == '__main__':
    img = torch.randn(2, 3, 224, 224)
    net = Net()
    sample = net(img)
    print(sample.shape)

训练代码:


# python
# 导入必要的库
import os  # 导入操作系统库,用于文件操作
import model  # 导入自定义的模型模块
import torch  # 导入PyTorch库
import torch.nn as nn  # 导入PyTorch神经网络模块
import torch.optim as optim  # 导入PyTorch优化器模块
import numpy as np  # 导入NumPy库,用于数组操作
from load_img import MyDataset  # 从load_img模块中导入自定义的MyDataset类
from torchvision import transforms  # 导入torchvision的transforms模块,用于图像预处理
from torch.utils.data import DataLoader  # 导入PyTorch的数据加载器模块

# 设置超参数
batchsize = 8  # 设置每个批次的大小为8
epochs = 50  # 设置训练的总轮数为50
train_data_path = 'data/train'  # 设置训练数据的路径

# 定义图像预处理流程:转换为tensor并归一化
transform = transforms.Compose([
    transforms.ToTensor(),  # 将图像转换为Tensor
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 归一化处理,使用预定义的均值和标准差
])

# 加载数据集,并设置批处理大小和是否打乱数据
bag = MyDataset(train_data_path, transform)  # 初始化MyDataset类,加载数据并应用预处理
dataloader = DataLoader(bag, batch_size=batchsize, shuffle=True)  # 使用DataLoader来加载数据,设置批次大小和打乱数据

# 选择使用GPU进行计算
device = torch.device('cuda')  # 设置设备为CUDA(即GPU)

# 将模型加载到GPU上
net = model.Net().to(device)  # 初始化模型,并将其移动到GPU上

# 设置损失函数和优化器
criterion = nn.BCELoss()  # 使用二分类交叉熵损失函数
optimizer = optim.SGD(net.parameters(), lr=1e-2, momentum=0.7)  # 使用随机梯度下降优化器,设置学习率和动量

# 检查是否存在保存模型的文件夹,如果不存在则创建
if not os.path.exists('checkpoints'):
    os.mkdir('checkpoints')

# 开始训练循环
for epoch in range(1, epochs + 1):  # 对每个epoch进行循环
    for batch_idx, (img, lab) in enumerate(dataloader):  # 对每个batch的数据进行循环
        img, lab = img.to(device), lab.to(device)  # 将数据和标签移动到GPU上

        # 通过模型进行前向传播,并使用sigmoid函数得到输出
        output = torch.sigmoid(net(img))  # sigmoid函数用于将输出转换为概率值

        # 计算损失
        loss = criterion(output, lab)  # 使用损失函数计算损失值

        # 每20个batch打印一次损失值
        if batch_idx % 20 == 0:
            print('Epoch:[{}/{}]\tStep:[{}/{}]\tLoss:{:.6f}'.format(
                epoch, epochs, (batch_idx + 1) * len(img), len(dataloader.dataset), loss.item()
            ))

            # 清空梯度,反向传播,更新权重
        optimizer.zero_grad()  # 清空梯度
        loss.backward()  # 反向传播计算梯度
        optimizer.step()  # 更新模型的权重

    # 每10个epoch保存一次模型
    if epoch % 10 == 0:
        torch.save(net, 'checkpoints/model_epoch_{}.pth'.format(epoch))  # 保存模型
        print

测试代码:

# 导入必要的库  
import torch                        # 导入PyTorch库  
import cv2                          # 导入OpenCV库,用于图像处理  
from torch.utils.data import Dataset, DataLoader  # 从PyTorch库中导入Dataset和DataLoader,用于构建数据集和加载数据  
from torchvision import transforms  # 从PyTorch的vision库中导入transforms,用于图像预处理  
import numpy as np                 # 导入NumPy库,用于数值计算  
import os                          # 导入os库,用于处理文件路径  
  
# 定义一个名为TestDataset的类,继承自Dataset  
class TestDataset(Dataset):  
    def __init__(self, test_img_path, transform=None):  
        # 初始化方法,接收测试图像的路径和转换方法作为参数  
        self.test_img = os.listdir(test_img_path)  # 获取测试图像路径下的所有文件名  
        self.transform = transform                  # 将转换方法保存为类的属性  
        self.images = []                             # 初始化一个空列表,用于存储完整的图像路径  
        for i in range(len(self.test_img)):         # 遍历所有文件名  
            self.images.append(os.path.join(test_img_path, self.test_img[i]))  # 拼接完整的图像路径并添加到列表中  
  
    def __getitem__(self, item):  
        # 根据索引获取图像的方法  
        img_path = self.images[item]                # 根据索引获取图像的完整路径  
        img = cv2.imread(img_path)                  # 使用OpenCV读取图像  
        img = cv2.resize(img, (224, 224))          # 将图像缩放到224x224的大小  
        if self.transform is not None:             # 如果有转换方法  
            img = self.transform(img)               # 使用转换方法处理图像  
        return img                                  # 返回处理后的图像  
  
    def __len__(self):  
        # 返回数据集的长度的方法  
        return len(self.test_img)                  # 返回图像文件名的数量  
  
# 定义测试图像的路径和模型检查点的路径  
test_img_path = 'data/test/last'  
checkpoint_path = 'checkpoints/model_epoch_10.pth'  
  
# 定义图像转换的流水线  
transform = transforms.Compose([transforms.ToTensor(),  # 将图像转换为Tensor  
                                transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])  # 对图像进行归一化处理  
  
# 使用定义的TestDataset类创建数据集对象  
bag = TestDataset(test_img_path, transform)  
  
# 使用DataLoader加载数据集  
dataloader = DataLoader(bag, batch_size=1, shuffle=None)  # 批处理大小为1,不打乱数据顺序  
  
# 加载模型检查点  
net = torch.load(checkpoint_path)  
  
# 将模型移动到GPU上  
net = net.cuda()  
  
# 遍历数据加载器中的每一个数据批次  
for idx, img in enumerate(dataloader):  
    # 将图像数据移动到GPU上  
    img = img.cuda()  
      
    # 前向传播,得到模型输出  
    output = torch.sigmoid(net(img))  # 对输出应用sigmoid函数,将其转换为概率值  
  
    # 将输出从GPU转移到CPU,并转换为NumPy数组  
    output_np = output.cpu().data.numpy().copy()  
      
    # 找到每个样本输出中的最小值索引  
    output_np = np.argmin(output_np, axis=1)  
      
    # 挤压数组,移除可能的单维度条目  
    img_arr = np.squeeze(output_np)  
      
    # 将索引值转换为0-255的范围(这看起来是不正确的,因为索引通常是整数,而不是概率值)  
    img_arr = img_arr*255  
      
    # 保存结果图像  
    cv2.imwrite('result/%03d.png'%idx, img_arr)  
      
    # 打印保存的图像的文件名  
    print('result/%03d.png'%idx)

结果展示:

4、所以分割网络到底是什么?

代码就是上面那些,直接运行的话也是可以的,但是我还是不理解分割到底是怎么进行运算的?

继续理解吧。

首先,模型代码分析

encode代表编码器,一共有5个encode,操作就是进行卷积+下采样

decode代表解码器,同样得有5个decode,操作就是进行卷积+上采样

最后一个分类器classifier,进行分类,

注意它的输出shape是1 x 2 x 224 x 224

代表: batch  x channels x weight x height  #batch  通道数  宽 高

注意这里的channel是前景类别 + 背景   #例如上面的类别是2,代表只有一个前景和一个背景输出的tensor是这样的

tensor([[[[ 3.1585,  3.3064,  3.1652,  ...,  3.3435,  3.2202,  3.1270],
          [ 3.2913,  3.4627,  3.4873,  ...,  3.4024,  3.3583,  3.0580],
          [ 3.3163,  3.4247,  3.2877,  ...,  3.4584,  3.1003,  3.1352],
          ...,
          [ 3.3558,  3.0914,  3.2765,  ...,  3.3156,  3.3142,  3.0663],
          [ 3.3003,  3.2883,  3.0972,  ...,  3.3562,  3.2461,  3.1394],
          [ 3.1776,  2.7403,  3.0708,  ...,  2.8127,  3.1564,  2.8254]],
         [[-3.1017, -3.2601, -3.1177,  ..., -3.2974, -3.1925, -3.0627],
          [-3.2573, -3.6687, -3.4113,  ..., -3.6558, -3.3187, -3.0988],
          [-3.2599, -3.2627, -3.2116,  ..., -3.3546, -3.0332, -3.1106],
          ...,
          [-3.3207, -3.2899, -3.2340,  ..., -3.5797, -3.2753, -3.0780],
          [-3.2396, -3.2038, -3.0360,  ..., -3.2971, -3.1837, -3.0911],
          [-3.1533, -2.7486, -3.0507,  ..., -2.8135, -3.1188, -2.8821]]]],
       device='cuda:0', grad_fn=<ConvolutionBackward0>)
 

然后,测试代码分析

在这个代码里注意看前向传播这里。

output = torch.sigmoid(net(img))

这里sigmoid是将数据归一化到0-1范围内,输出的数据是这样的

tensor([[[[0.9592, 0.9646, 0.9595,  ..., 0.9659, 0.9616, 0.9580],
          [0.9641, 0.9696, 0.9703,  ..., 0.9678, 0.9664, 0.9551],
          [0.9650, 0.9685, 0.9640,  ..., 0.9695, 0.9569, 0.9583],
          ...,
          [0.9663, 0.9565, 0.9636,  ..., 0.9650, 0.9649, 0.9555],
          [0.9644, 0.9640, 0.9568,  ..., 0.9663, 0.9625, 0.9585],
          [0.9600, 0.9394, 0.9557,  ..., 0.9434, 0.9592, 0.9440]],

         [[0.0430, 0.0370, 0.0424,  ..., 0.0357, 0.0394, 0.0447],
          [0.0371, 0.0249, 0.0319,  ..., 0.0252, 0.0349, 0.0432],
          [0.0370, 0.0369, 0.0387,  ..., 0.0337, 0.0460, 0.0427],
          ...,
          [0.0349, 0.0359, 0.0379,  ..., 0.0271, 0.0364, 0.0440],
          [0.0377, 0.0390, 0.0458,  ..., 0.0357, 0.0398, 0.0435],
          [0.0410, 0.0602, 0.0452,  ..., 0.0566, 0.0423, 0.0530]]]],
       device='cuda:0', grad_fn=<SigmoidBackward0>)

还可以知道,单个像素点的tensor是这样的

tensor([[[[0.9592],
          [0.0430]],

         [[0.9641],
          [0.0371]],

         [[0.9650],
          [0.0370]],

         ...,

         [[0.9663],
          [0.0349]],

         [[0.9644],
          [0.0377]],

         [[0.9600],
          [0.0410]]],


        [[[0.9646],
          [0.0370]],

         [[0.9696],
          [0.0249]],

         [[0.9685],
          [0.0369]],

         ...,

         [[0.9565],
          [0.0359]],

         [[0.9640],
          [0.0390]],

         [[0.9394],
          [0.0602]]],


        [[[0.9595],
          [0.0424]],

         [[0.9703],
          [0.0319]],

         [[0.9640],
          [0.0387]],

         ...,

         [[0.9636],
          [0.0379]],

         [[0.9568],
          [0.0458]],

         [[0.9557],
          [0.0452]]],


        ...,


        [[[0.9659],
          [0.0357]],

         [[0.9678],
          [0.0252]],

         [[0.9695],
          [0.0337]],

         ...,

         [[0.9650],
          [0.0271]],

         [[0.9663],
          [0.0357]],

         [[0.9434],
          [0.0566]]],


        [[[0.9616],
          [0.0394]],

         [[0.9664],
          [0.0349]],

         [[0.9569],
          [0.0460]],

         ...,

         [[0.9649],
          [0.0364]],

         [[0.9625],
          [0.0398]],

         [[0.9592],
          [0.0423]]],


        [[[0.9580],
          [0.0447]],

         [[0.9551],
          [0.0432]],

         [[0.9583],
          [0.0427]],

         ...,

         [[0.9555],
          [0.0440]],

         [[0.9585],
          [0.0435]],

         [[0.9440],
          [0.0530]]]], device='cuda:0', grad_fn=<PermuteBackward0>)

从这三个tensor可以明白,针对二分类任务,经过模型输出的预测结果包含两个通道,一个通道里存储的是前景的预测概率值,另一个通道里存储的是背景的预测概率值。或者说单个像素点会被预测两个值,分别存储在不同的通道里。多类别任务以此类推。。。

继续

output_np = output.cpu().data.numpy().copy()

是numpy数组的转换

继续

output_np = np.argmin(output_np, axis=1)

这里np.argmin是取最小值索引的操作,维度沿着通道维度,axis=1

这句代码的作用是将 output_np 数组中的每个像素(或像素区域)的类别概率转换为对应的类别索引。

输出就是这样的:

然后就是:

img_arr = np.squeeze(output_np)

目的在于去掉batch维度。之后就是进行上色了。如果想在原图上展示,就是先生成蒙版,再与图像进行合成,注意设置透明度。

参考:

感谢博主:阿里云云栖号

感谢博主:一文读懂语义分割与实例分割 - 知乎

感谢博主:Pytorch搭建训练简单的图像分割模型_pytorch分割使用预训练模型-CSDN博客

初识分割,写的不对的地方,请大家指教!

标签:__,...,nn,img,浅浅,self,pytorch,图像
From: https://blog.csdn.net/weixin_46319994/article/details/136689191

相关文章

  • 机器学习 - PyTorch里的aggregation
    在PyTorch里,可以在tensor里找到min,max,mean,sum等aggregation值。直接上代码importtorchx=torch.arange(0,100,10)print(x)print(f"Minimum:{x.min()}")print(f"Minimum:{torch.min(x)}")print(f"Maximum:{x.max()}")print(f"Maxi......
  • 超分辨率(2)--基于EDSR网络实现图像超分辨率重建
    目录一.项目介绍二.项目流程详解2.1.构建网络模型2.2.数据集处理2.3.训练模块2.4.测试模块三.测试网络一.项目介绍EDSR全称EnhancedDeepResidualNetworks,是SRResnet的升级版,其对网络结构进行了优化(去除了BN层),省下来的空间可以用于提升模型的size来增强表现力。......
  • 【火灾检测】基于matlab GUI视频图像多特征火灾检测报警系统【含Matlab源码 4092期】
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信。......
  • LabVIEW多表位数字温湿度计图像识别系统
    LabVIEW多表位数字温湿度计图像识别系统解决数字温湿度计校准过程中存在的大量需求和长时间校准问题,通过LabVIEW开发平台设计了一套适用于20多个表位的数字温度计图像识别系统。该系统能够通过图像采集、提取和处理,进行字符训练,从而实现对不同型号数字温湿度计的温度和湿度字......
  • pytorch CV入门 - 汇总
    初次编辑:2024/2/14;最后编辑:2024/3/9参考网站-微软教程:https://learn.microsoft.com/en-us/training/modules/intro-computer-vision-pytorch更多的内容可以参考本作者其他专栏:Pytorch基础:https://blog.csdn.net/qq_33345365/category_12591348.htmlPytorchNLP基础:https......
  • Pytorch基础-汇总
    本教程翻译自微软教程:https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/初次编辑:2024/3/1;最后编辑:2024/3/4本教程包含以下内容:介绍pytorch基础和张量操作介绍数据集介绍归一化介绍构建模型层的基本操作介绍自动微分相关知识介绍优化循环(optimiz......
  • 微信小程序开发:异步处理接入的生成式图像卡通化
    书接上文,我们完成了对接阿里云人像动漫化接口,现已完成的界面是这样的: 就是效果看着一般,看看效果: 然后我就在阿里云api市场转悠,就想看看还有没有什么其他奇奇怪怪的api,结果就发现了这个:api链接这里:https://help.aliyun.com/zh/viapi/api-generative-image-cartoon ......
  • 基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的癌症图像检测系统(深度学习模型+UI界面代码+训练数
    摘要:本文介绍了一种基于深度学习的癌症图像检测系统的代码,采用最先进的YOLOv8算法并对比YOLOv7、YOLOv6、YOLOv5等算法的结果,能够准确识别图像、视频、实时视频流以及批量文件中的摘要:本篇博客深入介绍了如何借助深度学习技术开发癌症图像检测系统,以提高医疗诊断的精度和速度。系......
  • pytorch使用pytorch_wavelets包错误:ValueError: step must be greater than zero 错误
    错误描述在使用pytorch_wavelets包的DWT1DInverse时,发现报错信息如下:Traceback(mostrecentcalllast):File"/work/GDN/test/test_DWT.py",line24,inx_=idwt((YL,YH))File"/opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py",line550......
  • 基于深度学习算法的垃圾分类图像识别研究
    概要  在科技发达、智能时代中,深度学习、机器学习以及人工智能成为了高频词。它们看似深不可测,但是又离不开我们的生活。深度学习和机器学习是一种技术、而人工智能一种是一种体现。使用深度学习和机器技术,使机器拥有人的某种大脑结构从而来实现人的某种行为,它不仅解决了......