利用卷积神经网络实现对图片的分类


# 数据导入
import tensorflow as tf
(x, y), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook


plt.imshow(x[49999])  #显示第一张图片
#plt.imshow(x_test[9999])

x = x/255    #归一化   目标:把数变为(0,1)之间的小数
x_test = x_test/255
# 模型搭建
model = tf.keras.Sequential([
    #Input()函数用于实例化keras张量
    tf.keras.Input(shape=(32,32,3)),
    #filters:卷积过滤器的数量,对应输出的维数
    #kernel_size:整数,过滤器的大小,如果为一个整数则宽和高相同
    #padding:valid:表示不够卷积核大小的块,则丢弃;
            #same表示不够卷积核大小的块就补0,所以输出和输入形状相同
    #activation:激活函数
    tf.keras.layers.Conv2D(filters=32 ,kernel_size=3 , padding='same', activation='relu'),
    tf.keras.layers.Dropout(0.25),
    #pool_size:用于指定池窗口的大小
    #strides:用于指定池操作的步幅
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2),strides=(2,2)),
    tf.keras.layers.Conv2D(filters=64 ,kernel_size=3 , padding='same', activation='relu'),
    tf.keras.layers.Dropout(0.25),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2),strides=(2,2)),
    tf.keras.layers.Conv2D(filters=128 ,kernel_size=3 , padding='same', activation='relu'),
    tf.keras.layers.Dropout(0.25),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2),strides=(2,2)),
    # 池化层
    #Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡
    tf.keras.layers.Flatten(),
    #全连接层
    tf.keras.layers.Dense(1024, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])
model.summary()
# 模型编译
model.compile(
    #optimizer:此对象会指定训练过程。
                #从 tf.train 模块向其传递优化器实例,
                #例如 AdamOptimizer、RMSPropOptimizer 或 GradientDescentOptimizer。
        #learning_rate:学习率
    optimizer = tf.keras.optimizers.Adam(learning_rate=0.01),
    #loss:损失函数
    loss = tf.keras.losses.sparse_categorical_crossentropy,
    metrics = ['acc']
# 模型训练
batches = 50
batch_size = 20000
data = []
for i in range(batches):
    index=np.random.choice(x.shape[0],batch_size,replace=False) #从训练集随机选取20000个数据,replace:意味挑选数据不重复
    x_batch = x[index]
    y_batch = y[index]
    #使用.fit方法进行测试数据与模型的拟合
    history = model.fit(x_batch,y_batch, batch_size=1000, validation_split=0.2)# 训练
    hist = pd.DataFrame(history.history)
    data.append(hist)

df = pd.concat(data).reset_index(drop=True)
def plot_history(hist):
    plt.figure(figsize=(10,5))
    # subplot(1,2,1): 一行两列第一个图
    plt.subplot(1,2,1)
    plt.xlabel('Epoch')
    plt.plot(hist['loss'],
           label='loss')
    plt.plot( hist['val_loss'],
           label='val_loss')
    plt.legend()
    plt.subplot(1,2,2)
    plt.xlabel('Epoch')
    plt.plot( hist['acc'],
           label = 'acc',color = 'red')
    plt.plot( hist['val_acc'],
           label = 'val_acc')
    plt.legend()
    
plot_history(df)
# 模型评估
model.evaluate(x_test, y_test, verbose=2)
# 模型预测
def writePre(pre,class_names):
    for i in range(len(class_names)):
        if pre == class_names[i]:
            return i
def writeTar(tar,class_names):
    for i in range(len(class_names)):
        if tar == class_names[i]:
            return i

prediction = model.predict(x_test)
class_names = ['飞机','汽车','鸟','猫','鹿','狗','青蛙','马','船','卡车']
for x in range(10):
    num = 0
    n = 0
    num_1 = 0
    n_1 = 0
    sj = class_names[x]
    for i in range(10000):
        # 预测
        pre = class_names[np.argmax(prediction[i])]
        #  实际
        tar = class_names[y_test[i][0]]
    #     print("预测:%s   实际:%s" % (pre, tar))
    #     print(pre)
        if pre == sj:
            if tar == sj:
                num += 1
            else:
                n += 1                
        if tar == sj:
            if pre == sj:
                num_1 += 1
            else:
                n_1 += 1                
    jql = num/(num+n)  
    zhl = num_1/(num_1+n_1)
    f1 = (2*jql*zhl)/(jql+zhl)
    print("预测%s 的精确率为: %s" %(sj,jql))
    print("预测%s 的召回率为: %s" %(sj,zhl))
    print("f1值为: %s" %(f1))
y_true = []
y_pred = []
for i in range(10000):
    pre = class_names[np.argmax(prediction[i])]
    tar = class_names[y_test[i][0]]
    y_pred.append(writePre(pre,class_names))
    y_true.append(writeTar(tar,class_names))
# 混淆矩阵
from sklearn.metrics import confusion_matrix
plt.rcParams['axes.unicode_minus']=False # 显示中文
plt.rcParams['font.sans-serif'] = ['SimHei'] #指定默认字体  

classes = ['飞机','汽车','鸟','猫','鹿','狗','青蛙','马','船','卡车']
confusion = confusion_matrix(y_pred, y_true)
print(confusion)
plt.figure(figsize=(10,5))
plt.imshow(confusion, cmap=plt.cm.Blues)
indices = range(len(confusion))
plt.xticks(indices, classes)
plt.yticks(indices, classes)
plt.colorbar()
plt.ylabel('Pred')
plt.xlabel('True')
for first_index in range(len(confusion)):
    for second_index in range(len(confusion[first_index])):
        plt.text(second_index, first_index,confusion[first_index][second_index])
plt.show()
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值