一张图片如何在三个分类图片中识别,程序如何修改,如何添加?

问题遇到的现象和发生背景

我想用猫狗识别程序 框架 在 猫狗两类识别基础上,增加第三类识别,不知道以下程序修改得是否正确,如何改? 模拟应用 模块 不知道怎么改 才能达到 一张图片在 三个分类中识别?麻烦帮忙改下以下程序,谢谢了!

用代码块功能插入代码,请勿粘贴截图


#---------------------------------------构建样本集程序-----------------------------------------------
import cv2 as cv
import numpy as np
import os 

if __name__=='__main__':
    l_x=128 #输入X的长宽
    #样本数量
    m=1000#样本总数
    m1=100#训练集数量
    m2=50#测试集数量

    train_set=np.zeros(m1*3*l_x*l_x*3)#创建零矩阵
    train_set=np.reshape(train_set,(m1*3,3,l_x,l_x))#重塑成可以存储图像的行政

    test_set=np.zeros(m2*3*l_x*l_x*3)#创建零矩阵
    test_set=np.reshape(test_set,(m2*3,3,l_x,l_x))#重塑成可以存储图像的形状
    sucess_mark=0#成功标记

    #构建训练集
    for i in range(m1):
        #path1=f'./train/cat.{i}.jpg'#训练图片路径
        #path2=f'./train/dog.{i}.jpg'

        path1=f'./xllz/train/hftl3/{i}.jpg'
        path2=f'./xllz/train/hfzt3/{i}.jpg'
        path3=f'./xllz/train/hfsl3/{i}.jpg'

        if os.path.exists(path1) & os.path.exists(path2) & os.path.exists(path3):
            img1=cv.imread(path1)#读取训练图片,转换灰色图片
            img2=cv.imread(path2)#读取训练图片
            img3=cv.imread(path3)#读取训练图片

            img1=cv.resize(img1,(l_x,l_x))#将图片调整规定的尺寸
            img2=cv.resize(img2,(l_x,l_x))
            img3=cv.resize(img3,(l_x,l_x))
        
            train_set[i,0,:,:]=img1[:,:,0]#赋值给训练集矩阵
            train_set[i,1,:,:]=img1[:,:,1]
            train_set[i,2,:,:]=img1[:,:,2]
            sucess_mark+=1

            print("\r"+f'训练集总数:{m1*3},xl当前第{(i+1)*3}个',end="",flush=True)
            train_set[m1+i,0,:,:]=img2[:,:,0]
            train_set[m1+i,1,:,:]=img2[:,:,1]
            train_set[m1+i,2,:,:]=img2[:,:,2]
            sucess_mark+=1

            train_set[m1+m1+i,0,:,:]=img3[:,:,0]
            train_set[m1+m1+i,1,:,:]=img3[:,:,1]
            train_set[m1+m1+i,2,:,:]=img3[:,:,2]
            sucess_mark+=1


        else:
            print(f'路径{path1}{path2}{path3}不存在0!')
            break
  
    pww=input("hello")
    #构建测试集
    for i in range(100,150):

        path1=f'./xllz/train/hftl3/{i}.jpg'
        path2=f'./xllz/train/hfzt3/{i}.jpg'
        path3=f'./xllz/train/hfsl3/{i}.jpg'

    
        if os.path.exists(path1) & os.path.exists(path2) & os.path.exists(path3):

            img1=cv.imread(path1)
            img2=cv.imread(path2)
            img3=cv.imread(path3)

            img1=cv.resize(img1,(l_x,l_x))
            img2=cv.resize(img2,(l_x,l_x))
            img3=cv.resize(img3,(l_x,l_x))

            test_set[i-100,0,:,:]=img1[:,:,0]#赋值给测试集矩阵
            test_set[i-100,1,:,:]=img1[:,:,1]
            test_set[i-100,2,:,:]=img1[:,:,2]
            sucess_mark+=1
            print("\r"+f'测试集总数:{m2*3},cs当前第{(i-100+1)*3}个',end="",flush=True)

            test_set[m2+i-100,0,:,:]=img2[:,:,0]
            test_set[m2+i-100,1,:,:]=img2[:,:,1]
            test_set[m2+i-100,2,:,:]=img2[:,:,2]
            sucess_mark+=1
           
            test_set[m2+m2+i-100,0,:,:]=img3[:,:,0]
            test_set[m2+m2+i-100,1,:,:]=img3[:,:,1]
            test_set[m2+m2+i-100,2,:,:]=img3[:,:,2]
            sucess_mark+=1



        else:
            print(f'路径{path1}{path2}{path3}不存在1!')
            break
    print(str(sucess_mark))

    if sucess_mark==450:#如果样本总数否则保存两个数据集
        np.save('cat_train_set.npy',train_set)
        np.save('cat_test_set.npy',test_set)
        print('生成成功!')
        
#-------------------测试样本集-----------------------------
import cv2 as cv
import numpy as np
train_set=np.load('cat_train_set.npy')
test_set=np.load('cat_test_set.npy')

for i in range(1000):
    i=400+i
    img1=train_set[i,0,:,:]#数字根据生成样本规格数字输入
    #img2=test_set[50,0,:,:]

    img1=img1.astype(np.uint8)#由float转换uint8格式
    #img2=img2.astype(np.uint8)
    cv.imshow('q.jpg',img1)#显示图片
    #cv.imshow('sl50.jpg',img2)
    cv.waitKey(0)


"""
实战2
代码8-3
识别猫狗的卷积神经网络模型
"""
import torch.nn as nn                        # 引入torch.nn模块


class ICNET(nn.Module):                       # 定义类存储网络结构
    def __init__(self):
        super(ICNET, self).__init__()
        self.ConvNet = nn.Sequential(       # nn模块搭建卷积网络
            nn.Conv2d(in_channels=3, out_channels=8, kernel_size=3, stride=1, padding=1,
                      bias=False),          # size:128,128,8
            nn.ReLU(inplace=True),
            nn.Conv2d(in_channels=8, out_channels=8, kernel_size=3, stride=1, padding=1,
                      bias=False),          # size:128,128,8
            nn.ReLU(inplace=True),          # ReLU激活函数
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0),  # size:64,64,18

        )
        self.LinNet = nn.Sequential(       # nn模块搭建网络
            nn.Linear(64*64*8, 1000),      # 全连接层
            nn.ReLU(inplace=True),         # ReLU激活函数
            nn.Linear(1000, 1000),
            nn.ReLU(inplace=True),
            nn.Linear(1000, 3),
            nn.Softmax(dim=1)              # SoftMax分类激活函数
        )

    def forward(self, x):                   # 定义前向传播过程
        x = self.ConvNet(x)                 # 将x传入卷积网络
        x = x.view(x.size(0), 64*64*8)      # 展成一维数组
        out = self.LinNet(x)                # 接着通过全连接层
        return out                          # 返回预测值



"""

识别猫的卷积神经网络训练程序
(附加可视化)
"""
from net_model import ICNET                                 # 引入网络模型
import torch                                                # 引入torch模块
import torch.nn as nn                                       # 引入torch.nn模块
import numpy as np                                          # 引入np模块
import matplotlib.pyplot as plt                             # 引入matplotlib模块

net = ICNET().cpu()                                        # 将网络传入GPU
x = np.load(file="cat_train_set.npy") / 255                 # 载入训练集并进行简单归一化
x = torch.tensor(x).type(torch.FloatTensor).cpu()          # 转换成tensor变量并传入GPU
y1 = torch.zeros(150)
y2 = torch.ones(150)
y = torch.cat((y1, y2)).type(torch.LongTensor)
optimizer = torch.optim.SGD(net.parameters(), lr=0.03)      # 设置优化器
loss_func = nn.CrossEntropyLoss()                           # 设置损失函数

samplenum = 300       # 样本总数(训练集总数)
minibatch = 30      # 小批次样本大小

w_HR = 128           # 样本尺寸
x0 = np.zeros(minibatch * 3 * w_HR * w_HR)
x0 = np.reshape(x0, (minibatch, 3, w_HR, w_HR))       # 创建小批次空白样本
y0 = np.zeros(minibatch)                              # 创建小批次空白标签
x0 = torch.tensor(x0).type(torch.FloatTensor).cpu()
y0 = torch.tensor(y0).type(torch.LongTensor).cpu()   # 将小批次样本和标签传入GPU

plt.ion()       # 开启交互模式
x_plt = [0]     # x坐标
y_plt = [0]     # y坐标

plt.show()  # 显示最后一幅图
for epoch in range(80):                                             # epoch循环
    print("训练进度:"+str(epoch))


    for iterations in range(int(samplenum / minibatch)):              # iterations循环
        k = 0
        for i in range(iterations * minibatch, iterations * minibatch + minibatch):     # 部分样本赋值给x0的循环
            x0[k, 0, :, :] = x[i, 0, :, :]
            x0[k, 1, :, :] = x[i, 1, :, :]
            x0[k, 2, :, :] = x[i, 2, :, :]
           
            y0[k] = y[i]         # 小批次标签
            k = k + 1
            

        out = net(x0)                                     # 实际输出
        loss = loss_func(out, y0)                         # 实际输出和期望输出传入损失函数
        optimizer.zero_grad()                             # 清除梯度
        loss.backward()                                   # 误差反向传播
        optimizer.step()                                  # 优化器开始优化
    if epoch % 10 == 0:# 每50次显示

        plt.cla()            # 清除上一次绘图
        plt.xlim((0, 1000))  # 设置x坐标范围
        plt.xlabel('epoch')  # x轴的标题
        plt.ylim((0, 1))  # 设置y坐标范围
        plt.ylabel('loss')  # y轴的标题
        x_plt.append(epoch)  # 增加x坐标
        y_plt.append(loss.data) # 增加y坐标
        plt.plot(x_plt, y_plt, c='r', marker='x')  # 绘制折线图
        print(f'epoch:{epoch},loss:{loss}')     # 打印中间过程
        plt.pause(0.1)      # 停留显示
print("循环完成")
plt.ioff()  # 关闭交互模式
print("循环完成1")

print("zwc")
torch.save(net, 'net1.pkl')                                # 保存网络
print("wc")
plt.show()  # 显示最后一幅图



#------------------测试网络程序-------------------------------------
import torch
import numpy as np
net=torch.load('net1.pkl')
x=np.load(file="cat_test_set.npy")/255#载入测试集并简单进行归一化
x=torch.tensor(x).type(torch.FloatTensor).cpu()#转换成Tensor变量并传入gpu
y1=torch.zeros(75)
y2=torch.ones(75)

y0=torch.cat((y1,y2))#将两个张量拼接在一起 设置标签用来计算准确率
y=net(x)#输入网络得到结果
a1=torch.max(y,1)[1].cpu().data.numpy()#数据传回CPU 返回数字较大的坐标
a2=y0.data.numpy()#标签转换成numpy数组
print(f'准确率:{sum(a1==a2)/150}')#输出准确率


#--------------模拟识别应用--------------------------------------------------------------

import torch #导入 torch模块
import numpy as np#导入np 模块
import cv2 as cv#导入cv模块

net=torch.load('net1.pkl')#导入PKL网络
img=cv.imread("xllz\\zh\\tl1.jpg")#读取图像
img0=cv.resize(img,(128,128))#更改尺寸
x=np.zeros(128*128*3)#新建空白输入
x=np.reshape(x,(1,3,128,128))#调整到规定维度
x[0,0,:,:]=img0[:,:,0]/255#赋值输入并进行简单归一化
x[0,1,:,:]=img0[:,:,1]/255
x[0,2,:,:]=img0[:,:,2]/255


x=torch.tensor(x).type(torch.FloatTensor).cpu()#转换成tensor变量并传入CPU
y=net(x)#输入网络结果
#听力9
print(y)
max_num=torch.max(y,0)[1]#返回最大值下标
print(max_num)

print(str(max_num))



if max_num==0:
    print('听力')
    
if max_num==1:
     print('肢体')
else:

     print('视力')



cv.imshow(f'{str}',img)
cv.waitKey(0)


运行结果及报错内容

img

我的解答思路和尝试过的方法

在 构建数据集 网络训练 测试网络 已经增加了第三类识别,不知道程序修改是否正确,正在尝试在 模拟应用 模块增加第三类识别,无法按最接近图片 的一个结果 判断,却出现2个 结果

我想要达到的结果

之前两类识别,分辨率很高,想要增加到 第三类 图片行进识别,达到 图片在 三个分类中进行识别。

3 分类识别,就是 2个二分类 识别的并联

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632