データ融合ニューラルネットワークモデル データデータセット画像分類

画像分類にニューラル ネットワーク モデルを使用する (データセット Data)

独自のニューラル ネットワークを設計するか、既存のネットワークを使用してトレーニング データに基づいてトレーニングします

トレーニング済みのモデルを使用することはできません。自分でトレーニングしてから、トレーニング済みのモデルをテスト データでテストする必要があります。

自分でパラメータを調整する必要がある

データ データセット、3 つのラベル データ (馬、飛行機、車)

import warnings
warnings.filterwarnings("ignore")

import datetime

import matplotlib.pyplot as plt

import time

starttime = datetime.datetime.now()

import numpy as np
#from sklearn.cross_validation import train_test_split
from sklearn.model_selection import train_test_split

from sklearn.metrics import confusion_matrix, classification_report
#error:UndefinedMetricWarning:
# Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.
# Use `zero_division` parameter to control this behavior.
#  _warn_prf(average, modifier, msg_start, len(result))
#https://blog.csdn.net/qq_43391414/article/details/120543028
import os
import cv2

X = []
Y = []

width = 256
height = 256
# for i in range(0, 10):
for i in range(0+1, 3+1):
    # 遍历文件夹,读取图片
    # for f in os.listdir("./photo/%s" % i):
    # for f in os.listdir("./data/data/train"):
    # for f in os.listdir("./test2"):
    for f in os.listdir("./data/data/train/%s" %i):
    # for f in os.listdir("./data/data/train"):
        # 打开一张图片并灰度化
        # Images = cv2.imread("./photo/%s/%s" % (i, f))
        # https: // blog.csdn.net / weixin_44015965 / article / details / 109547129
        # Images = cv2.imread("./data/data/train/%s" % f)
        Images = cv2.imread("./data/data/train/%s/%s" % (i,f))
        #图片放缩
        image = cv2.resize(Images, (256, 256), interpolation=cv2.INTER_CUBIC)
        # cv2.calcHist()函数的作用:
        # 通过直方图可以很好的对整幅图像的灰度分布有一个整体的了解,直方图的x轴是灰度值(0
        # ~255),y轴是图片中具有同一个灰度值的点的数目。而calcHist()函数则可以帮助我们统计一幅图像的直方图
        hist = cv2.calcHist([image], [0, 1], None, [256, 256], [0.0, 255.0, 0.0, 255.0])
        X.append((hist / 255).flatten())
        Y.append(i)
X = np.array(X)
Y = np.array(Y)
# 切分训练集和测试集
# X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=1)
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=300, random_state=1)
# test_size	若在0~1之间,为测试集样本数目与原始样本数目之比;若为整数,则是测试集样本的数目。
# random_state	随机数种子
# X_train	划分出的训练集数据(返回值)
# X_test	划分出的测试集数据(返回值)
# y_train	划分出的训练集标签(返回值)
# y_test	划分出的测试集标签(返回值)
# X	待划分的样本特征集合
# y	待划分的样本标签
from sklearn.preprocessing import LabelBinarizer
import random


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


def logistic_derivative(x):
    return logistic(x) * (1 - logistic(x))


class NeuralNetwork:

    def predict(self, x):
        # w , b
        for b, w in zip(self.biases, self.weights):
            # 计算权重相加再加上偏向的结果
            z = np.dot(x, w) + b
            # 计算输出值
            x = self.activation(z)
        return self.classes_[np.argmax(x, axis=1)]

# BP 算法是一个迭代算法,它的基本思想为:
# (1) 先计算每一层的状态和激活值,直到最后一层(即信号是前向传播的);
# (2) 计算每一层的误差,误差的计算过程是从最后一层向前推进的(这就是反向传播算法名字的由来);
# (3) 更新参数(目标是误差变小),迭代前面两个步骤,直到满足停止准则(比如相邻两次迭代的误差的差别很小)。
class BP(NeuralNetwork):

    def __init__(self, layers, batch):

        # 层
        self.layers = layers
        # 批处理
        self.batch = batch
        # 流
        self.activation = logistic
        #
        self.activation_deriv = logistic_derivative
        # length
        self.num_layers = len(layers)
        # 偏差 b
        self.biases = [np.random.randn(x) for x in layers[1:]]
        # 权重 w
        self.weights = [np.random.randn(x, y) for x, y in zip(layers[:-1], layers[1:])]

    def fit(self, X, y, learning_rate=0.2, epochs=1):
        print(learning_rate)

        # class sklearn.preprocessing.LabelBinarizer(neg_label=0, pos_label=1, sparse_output=False)
        labelbin = LabelBinarizer()
          # LabelBinarizer()
          # 是sklearn.preprocessing中的一个函数,通过这个函数可以实现机器学习中国对图像标签的独热编码。
          # 独热编码是一种二进制编码,通俗的讲独热编码主要满足以下几个条件:
          #
          # 图像有n类,则编码长度为n
          # 对第i类编码,只有第i位置1,其余为0(1 ≤ i ≤ n
        y = labelbin.fit_transform(y)
        # fit_transform(self, y)  设定或者初始化二进制分类器并开始对y进行转换
        self.classes_ = labelbin.classes_

        training_data = [(x, y) for x, y in zip(X, y)]
        n = len(training_data)
        print(n)
        for k in range(epochs):
            t = time.localtime()
            print(k,t)
            # 每次迭代都循环一次训练
            random.shuffle(training_data)
            # 搅乱训练集,让其排序顺序发生变化
            # print(self.batch)
            batches = [training_data[k:k + self.batch] for k in range(0, n, self.batch)]
            # print(batches)
            # 批量梯度下降
            for mini_batch in batches:
                x = []
                y = []
                for a, b in mini_batch:
                    x.append(a)
                    y.append(b)
                activations = [np.array(x)]
                # 向前一层一层的走
                for b, w in zip(self.biases, self.weights):
                    # 计算激活函数的参数,计算公式:权重.dot(输入)+偏向
                    z = np.dot(activations[-1], w) + b
                    # 计算输出值
                    output = self.activation(z)
                    # 将本次输出放进输入列表,后面更新权重的时候备用
                    activations.append(output)
                # 计算误差值
                error = activations[-1] - np.array(y)
                # 计算输出层误差率
                deltas = [error * self.activation_deriv(activations[-1])]

                # 循环计算隐藏层的误差率,从倒数第2层开始
                for l in range(self.num_layers - 2, 0, -1):
                    deltas.append(self.activation_deriv(activations[l]) * np.dot(deltas[-1], self.weights[l].T))

                # 将各层误差率顺序颠倒,准备逐层更新权重和偏向
                deltas.reverse()
                # 更新权重和偏向
                for j in range(self.num_layers - 1):
                    # 权重的增长量,计算公式,增长量 = 学习率 * (错误率.dot(输出值)),单个训练数据的误差
                    delta = learning_rate / self.batch * (
                        (np.atleast_2d(activations[j].sum(axis=0)).T).dot(np.atleast_2d(deltas[j].sum(axis=0))))
                    # 更新权重
                    self.weights[j] -= delta
                    # 偏向增加量,计算公式:学习率 * 错误率
                    delta = learning_rate / self.batch * deltas[j].sum(axis=0)
                    # 更新偏向
                    self.biases[j] -= delta
        return self


# clf0 = BP([X_train.shape[1], 10], 10).fit(X_train, y_train, epochs=100)

clf0 = BP([X_train.shape[1], 3], 4).fit(X_train, y_train, epochs=100)
# def fit(self, X, y, learning_rate=0.1, epochs=1):
        # def fit(self, X, y, learning_rate=0.2, epochs=10000):
        # 设定epochs为循环的最高次数,即到最高时就直接结束循环 X = np.a...

predictions_labels = clf0.predict(X_test)
print(confusion_matrix(y_test, predictions_labels))
print(classification_report(y_test, predictions_labels))
# classification_report(
# y_true,
# y_pred,
# labels=None,
# target_names=None,
# sample_weight=None,
# digits=2,
# output_dict=False,
# zero_division=“warn”
# )
#
# 参数	描述
# y_true	真实值 ,一维数组形式(也可以是列表元组之类的)
# y_pred	预测值,一维数组形式(也可以是列表元组之类的)
# labels	标签索引列表,可选参数,数组形式
# target_names	与标签匹配的名称,可选参数,数组形式
# sample_weight	样本权重,数组形式
# digits	格式化输出浮点值的位数。默认为2。当“output_dict”为“True”时,这将被忽略,并且返回的值不会四舍五入。
# output_dict	是否输出字典。默认为False,如果为True则输出结果形式为字典。
# zero_division	设置存在零除法时返回的值。默认为warn。如果设置为“warn”,这相当于0,但也会引发警告。

endtime = datetime.datetime.now()
print(endtime - starttime)

おすすめ

転載: blog.csdn.net/m0_54070377/article/details/131076019