数据融合神经网络模型Data数据集图像分类

使用神经网络模型,进行图像分类(数据集Data)

自己设计神经网络,或者使用现有网络,对训练数据进行训练

不许使用已经训练好的模型,需自己训练,然后将训练好的模型对测试数据进行测试

需自行调参

data数据集,三个标签数据(马,飞机,汽车)

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个警告信息,意思是在标签中没有预测样本时,精度无法定义并被设置为.。可以使用“zero_division”参数来控制这种行为。这个警告信息是由“_warn_prf(average,modifier,msg_start,len(result))”函数触发的。 ### 回答2: 这条警告提醒我们的是标签中存在预测值为0的情况,导致在计算精确率时会出现除0的情况,因此无法得到合理的精确率计算结果。这个问题在使用sklearn等机器学习库时比较常见,通常发生在数据不平衡的情况下,即某些标签的样本数非常少,甚至没有样本被正确预测到。 针对这个问题,可以通过将zero_division参数设置为1或其他合适的值来进行调整。这个参数控制的是如果一个标签没有被正确预测,则将精确率的分母设置为多少,避免出现除0错误。如果将这个参数设置为1,则表示如果某个标签没有被正确预测,则将该标签的精确率设置为0。当然,这个值也可以根据具体情况进行调整,如将其设置为0.5或更小的值,以尽可能利用已有的信息,避免丢失某些有用的精确率计算结果。 除了调整zero_division参数,还可以尝试其他方法来解决这个问题。例如,可以通过增加样本数来平衡类别,或者采用一些特殊的算法和技术来解决这个问题。当然,具体的解决方法也需要根据数据的特点和具体的问题进行选择和优化,从而得到更加准确和可靠的模型预测结果。 ### 回答3: 此警告信息提示的意思是:在标签中,未预测到任何样本,导致精度无法定义,因此被设置为0.0。使用`zero_division`参数可以控制这种行为。`_warn_prf(average, modifier, msg_start, len(result))`是函数内部的警告信息,用于提醒用户注意精度的计算方式。 在机器学习模型中,通常会将数据集分成训练集和测试集,然后用训练集进行模型训练,在测试集上测试模型的性能。在模型预测过程中,如果某些标签没有被正确预测,就会出现上述警告信息,此时需要注意控制`zero_division`参数,以避免除以0的错误,同时需要考虑重新调整标签或模型参数,以提高预测准确性。 在实际应用中,还需要针对不同的模型数据集选择适当的精度计算方法和参数,以保证模型的高效性和准确性。因此,对于机器学习领域的从业者来说,掌握精度计算的方法和技巧是非常重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值