|
|
import numpy as np
|
|
|
import pandas as pd
|
|
|
import lqmtest_x3_5_pool
|
|
|
import lqmtest_x3_2_load_data
|
|
|
import lqmtest_x3_4_conv_proc
|
|
|
import lqmtest_x3_6_fullconn
|
|
|
import lqmtest_x3_7_nonlinear
|
|
|
import lqmtest_x3_8_classify
|
|
|
import lqmtest_x3_9_label
|
|
|
|
|
|
class ModelObj: # 网络对象
|
|
|
def __init__(self, ObjID, ObjType, ObjLable, ParaString, ObjX, ObjY):
|
|
|
self.ObjID = ObjID # 图元号
|
|
|
self.ObjType = ObjType # 图元类别
|
|
|
self.ObjLable = ObjLable # 对象标签
|
|
|
self.ParaString = ParaString # 参数字符串
|
|
|
self.ObjX = ObjX # 对象位置x坐标
|
|
|
self.ObjY = ObjY # 对象位置y坐标
|
|
|
|
|
|
class Error_Class(ModelObj): # 误差计算对象
|
|
|
def __init__(self, ObjID, ObjType, ObjLable, ParaString, ObjX, ObjY):
|
|
|
super().__init__(ObjID, ObjType, ObjLable, ParaString, ObjX, ObjY)
|
|
|
self.ErrorProc = self.error_proc # 基本操作函数
|
|
|
self.SetErrorPara = self.seterror_para # 参数设置函数
|
|
|
def error_proc(self, input, label, ErrorPara):
|
|
|
label_list, loss_type = ErrorPara # 读取标签列表和损失函数类型
|
|
|
# 创建一个单位矩阵,大小为标签类别的个数
|
|
|
one_hot_matrix = np.eye(len(label_list))
|
|
|
index = [x for x in label]
|
|
|
label_one_hot = np.take(one_hot_matrix, index, axis=0)
|
|
|
# 确定损失函数类别,实现不同的损失函数,计算输入值与label之间的误差
|
|
|
if loss_type == "CEE": # 使用交叉熵损失函数
|
|
|
loss=-np.sum(label_one_hot*np.log(input))/len(input)
|
|
|
elif loss_type == "MSE": # 使用均方误差损失函数
|
|
|
loss = np.sum((input-label_one_hot)**2)/len(input)
|
|
|
elif loss_type == "MAE": # 使用平均绝对误差损失函数
|
|
|
loss=np.sum(np.abs(input-label_one_hot))/len(input)
|
|
|
else:
|
|
|
raise ValueError("Invalid loss type")
|
|
|
return loss # 返回误差值loss
|
|
|
def seterror_para(self): # 定义设置误差参数的函数
|
|
|
label_list = input("请输入标签类别列表(用逗号分隔):")
|
|
|
label_list = [int(x) for x in label_list.split(',')] # 确定参数信息: 标签类别
|
|
|
loss_type = input("请输入损失函数类型(CEE/MSE/MAE):") # 假设损失函数类型为交叉熵 CEE
|
|
|
# 返回ErrorProc参数,这里用一个元组来存储
|
|
|
ErrorPara = (label_list, loss_type)
|
|
|
return ErrorPara # 返回ErrorPara参数
|
|
|
if __name__ == '__main__':
|
|
|
DataSet = lqmtest_x3_2_load_data.Data_Class("DataSet1", 1, "数据集1", [], 120, 330)
|
|
|
# setload_data()函数,获取加载数据集的参数
|
|
|
DataPara = DataSet.SetDataPara()
|
|
|
train_images, test_images = DataSet.LoadData(DataPara)
|
|
|
|
|
|
Conv = lqmtest_x3_4_conv_proc.Conv_Class("Conv1", 2, "卷积1", [], 250, 330)
|
|
|
ConvPara = Conv.SetConvPara()
|
|
|
for i in range(len(train_images) // 32):
|
|
|
images = train_images[i * 32:(i + 1) * 32]
|
|
|
conv_images = [] # 存储卷积处理后的图片的列表
|
|
|
for image in images: # 获取训练集的图片数据
|
|
|
dim = len(image.shape) # 获取矩阵的维度
|
|
|
if dim == 2: # 如果是二维矩阵,则转化为三维矩阵
|
|
|
image_h, image_w = image.shape
|
|
|
image = np.reshape(image, (1, image_h, image_w))
|
|
|
# 调用ConvProc()函数,根据ConvPara参数完成卷积计算
|
|
|
output = Conv.ConvProc(image, ConvPara)
|
|
|
conv_images.append(output) # 将卷积结果存储到列表
|
|
|
elif dim == 3: # 若为三维矩阵,则保持不变直接卷积处理
|
|
|
output = Conv.ConvProc(image, ConvPara)
|
|
|
conv_images.append(output)
|
|
|
# 将卷积处理后的图片列表转换为数组形式,方便后续处理
|
|
|
conv_images = np.array(conv_images)
|
|
|
|
|
|
Pool = lqmtest_x3_5_pool.Pool_Class("Pool1", 3, "最大池化1", [], 380, 330)
|
|
|
PoolPara = Pool.SetPollPara()
|
|
|
pool_images = [] # 存储池化处理后的图片的列表
|
|
|
for image in conv_images: # 获取卷积后的图片数据
|
|
|
output = Pool.MaxPoolProc(image, PoolPara)
|
|
|
pool_images.append(output) # 将池化结果存储到列表
|
|
|
# 将池化处理后的图片列表转换为数组形式,方便后续处理
|
|
|
pool_images = np.array(pool_images)
|
|
|
|
|
|
_, _, poolH, poolW = pool_images.shape
|
|
|
FullConn = lqmtest_x3_6_fullconn.FullConn_Class("FullConn1", 4, "全连接1", [], 510, 330)
|
|
|
FullConnPara = FullConn.SetFullConnPara(poolH, poolW)
|
|
|
|
|
|
fullconn_images = [] # 存储全连接处理后的图片的列表
|
|
|
for image in pool_images: # 获取池化后的图片数据
|
|
|
output = FullConn.FullConnProc(image, FullConnPara)
|
|
|
fullconn_images.append(output) # 将全连接处理后的结果存储到列表
|
|
|
# 将全连接处理后的图片列表转换为数组形式,方便后续处理
|
|
|
fullconn_images = np.array(fullconn_images)
|
|
|
|
|
|
Nonline = lqmtest_x3_7_nonlinear.Nonline_Class("Nonline1", 5, "非线性函数1", [], 640, 330)
|
|
|
NonLPara = Nonline.SetNonLPara()
|
|
|
# 存储非线性处理后的图片的列表
|
|
|
nonlinear_images = []
|
|
|
for image in fullconn_images: # 获取全连接处理后的图片数据
|
|
|
output = Nonline.NonlinearProc(image, NonLPara)
|
|
|
# 将非线性处理后的结果存储到列表
|
|
|
nonlinear_images.append(output)
|
|
|
# 将非线性处理后的图片列表转换为数组形式,方便后续处理
|
|
|
nonlinear_images = np.array(nonlinear_images)
|
|
|
|
|
|
Classifier=lqmtest_x3_8_classify.Classifier_Class("Classifier1", 6, "分类1", [], 780, 330)
|
|
|
ClassifyPara = Classifier.SetClassifyPara()
|
|
|
classifier_images = [] # 存储分类处理后的图片的列表
|
|
|
prob_images = [] # 存储分类处理后的概率向量
|
|
|
for image in nonlinear_images: # 获取非线性处理后的图片数据
|
|
|
# 调用softmax函数,得到概率分布向量
|
|
|
prob = Classifier.softmax(image)
|
|
|
prob_images.append(prob) # 将概率向量结果存储到列表
|
|
|
output = Classifier.ClassifierProc(image, ClassifyPara)
|
|
|
classifier_images.append(output) # 将分类结果存储到列表
|
|
|
# 将分类的结果列表转换为数组形式,方便后续处理
|
|
|
classifier_images = np.array(classifier_images)
|
|
|
|
|
|
LabelPara = lqmtest_x3_9_label.Label()
|
|
|
label_dict = LabelPara.setlabel_para()
|
|
|
right_label = LabelPara.label_array(i)
|
|
|
labeled_samples = LabelPara.label_proc(images,
|
|
|
right_label, label_dict)
|
|
|
|
|
|
Error = Error_Class("Error1", 7, "误差计算1", [], 710, 124)
|
|
|
ErrorPara = Error.SetErrorPara()
|
|
|
# 输入值是一个概率矩阵,真实标签值是一个类别列表
|
|
|
prob_images = np.squeeze(prob_images)
|
|
|
loss = Error.ErrorProc(prob_images, right_label, ErrorPara)
|