【神经网络】一文带你轻松解析神经网络(附实例恶搞女友)_神经网络分析

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

在这里插入图片描述
我们通过a图可以看到在生物角度大概是分为树突,轴突和突触这三个部分。人工神经网络也大概是按照这个来做,输入得神经元可以看作是树突。然后箭头部分可以表示为轴突。最后得输出端可以看作是突触。
在这里插入图片描述

🎁三、神经网络前向传播

这里我们对应三个输入端,中间隐层可以看作是三个箭头,每一个箭头对应一个权重数值,然后传入到下一个神经元的时候得时候对权重进行求和,最后进行输出。
一个神经网络的训练算法就是让权重的值调整到最佳,以使得整个网络的预测效果最好。
简单来看,从输入到输出可以映射为一个非线性函数,通过很多个权重w,还有偏置项b。最终来确定输出得数值。细致一点得来说中间得计算过程就是线性代数中得矩阵得简单运算,但是计算量是巨大得,必须需要计算机来完成这个工作。
比如我们现在用神经网络做一个图片分类任务。

在这里插入图片描述
输入层通俗解释:比如说传进来一个小猫得图像,这个传输进来得图像就是经过数据预处理之后得图像他是一个32323得格式,也就是长是32,宽是32,然后channel是3道,也就是一个彩色图像,他就是和输出层神经元对应的。
中间隐层通俗解释:然后经过了箭头部分,可以看到箭头部分进行了权重的设置,最最开始权重参数是随机的,也可以是我们自己设置的,比如说迁移学习,就是说利用别人曾经训练好的最终权重参数来当我的开始训练参数,这里必须保证一点就是我们做的任务很相似!最终结果当然是好的,这里我们不过多介绍。那么这个随机参数设置结束后,经过权重参数运算之后就传入到了中间隐层部分。
输出层通俗解释:然后中间隐层继续传输,我们这里认为中间隐层就一层,然后最终经过了全连接层最终输出结果,这个全连接层有一个很重要的作用就是我们最终要做几分类,从这里可以完成。这里的三个操作完成了就相当于完成了一次前向传播。
比如说我们传入的是一张猫的图像,我们需要最终进行一个三分类的任务,比如是猫、狗、老鹰。
在这里插入图片描述
假如说我们现在的权重矩阵是一个103072的一个矩阵,然后我们最终想做一个10分类的结果,那么我们就要在全连接的层做一个相乘30721的,最终得到一个101的一个矩阵,然后我们还有做一个相应的微调,也就是偏置项b。因为做的是一个相加的操作,所以也是一个101的矩阵。这样最终对应的10中分类的得分我们就可以知道了。

🎁三、神经网络损失函数

在这里插入图片描述
加入这里我们得到了三种类别的得分,那么很明显它预测的不对!就说明他学习学的并不好,那么怎么让他学习学的更好呢?核心所在一定是我们这个权重矩阵了,那就是说怎么让这个权重矩阵越做越牛呢!那么我们就要对这个矩阵进行更新操作,这个操作就是我们所讲的神经网络的反向传播过程。具体是怎么样的呢?
说到反向传播,那么我们一定要说到的一点就是损失函数。
在这里插入图片描述
损失函数得分正值表示促进作用,负值表示对结果抑制作用。对应的公式右方通过他的计算过程也展现出来了!然后我们可以看得出来预测正确的损失函数最小,为0。那么预测错误的就不为0,相差的越大,损失值越大。
公式后面的+1表示容忍程度,表示至少要相差1以上。
当我们进行训练的时候,选择的模型要趋向于稳定,不要变异,我们要关注全局,而不是局部。
在这里插入图片描述
这里两个权重数值,W1,W2两个权重矩阵,然后计算出来的损失函数是一样的,但是两个矩阵很明显w2要比w1要更加稳定,更加适合。所以我们在计算损失函数的时候一定要进行正则化惩罚项。
在这里插入图片描述
这个就是计算损失函数的最终公式。
正则化项在神经网络中的重要作用
在这里插入图片描述

🎁四、神经网络分类器

  1. Softmax分类器
    Softmax分类器简单来说他就是一个多分类,像逻辑回归一样!
    在这里插入图片描述
    Softmax分类器输出的是概率值。
  2. Sigmoid分类器
    Sigmoid分类器就类似于二分类,是或者不是,可以或者不可以,能或者不能这样!输出的数值是0或者1.
    在这里插入图片描述
    损失函数我们一般都用交叉熵损失函数。这里我们对得分进行归一化的一个处理,就是先对得分进行以e为底,得分的幂数。然后进行一个归一化处理,就是计算各自的百分数,最后通过softmax公式计算概率。
    在这里插入图片描述

训练网络时的LOSS值视化结果。
在这里插入图片描述

🎁五、神经网络反向传播

在这里插入图片描述
我们走完了前向传播之后呢,得到了各自分类的损失函数,但是由于我们最开始设置的权重矩阵参数W是随机设置的,所以得到的结果一定不是好的,所以我们要根据最终得到的结果与真实结果进行对比,然后回头更新权重参数,然后让预测结果更准确。这就是反向传播的大概流程。
在这里插入图片描述

这里的绿色数字是前向传播的结果,通过前向传播得到下一个的得分。然后红色的数字是方向传播的结果,我们以最后一个为例子,就是

  • 加法门单元:均等分配
  • MAX门单元:给最大的
  • 乘法门单元:互换的感觉
    在这里插入图片描述
    越多的神经元,就越能够表达能复杂的模型
    在这里插入图片描述
    我们刚开始的时候就说到了这个神经网络的一个特性,就是数据的预处理和特征工程会决定整个网络的高度。
    在这里插入图片描述

🎁六、神经网络分类实战

预测模块
from keras.models import load_model
import argparse
import pickle
import cv2
#--image images/dog.jpg --model output/simple\_nn.model --label-bin output/simple\_nn\_lb.pickle --width 32 --height 32 --flatten 1
#--image images/dog.jpg --model output\_cnn/vggnet.model --label-bin output\_cnn/vggnet\_lb.pickle --width 64 --height 64
# 设置输入参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
	help="path to input image we are going to classify")
ap.add_argument("-m", "--model", required=True,
	help="path to trained Keras model")
ap.add_argument("-l", "--label-bin", required=True,
	help="path to label binarizer")
ap.add_argument("-w", "--width", type=int, default=28,
	help="target spatial dimension width")
ap.add_argument("-e", "--height", type=int, default=28,
	help="target spatial dimension height")
ap.add_argument("-f", "--flatten", type=int, default=-1,
	help="whether or not we should flatten the image")
args = vars(ap.parse_args())

# 加载测试数据并进行相同预处理操作
image = cv2.imread(args["image"])
output = image.copy()
image = cv2.resize(image, (args["width"], args["height"]))

# scale the pixel values to [0, 1]
image = image.astype("float") / 255.0
# 是否要对图像就行拉平操作
if args["flatten"] > 0:
	image = image.flatten()
	image = image.reshape((1, image.shape[0]))
# CNN的时候需要原始图像
else:
	image = image.reshape((1, image.shape[0], image.shape[1],
		image.shape[2]))
# 读取模型和标签
print("[INFO] loading network and label binarizer...")
model = load_model(args["model"])
lb = pickle.loads(open(args["label\_bin"], "rb").read())

# 预测
preds = model.predict(image)

i = preds.argmax(axis=1)[0]
label = lb.classes_[i]

text = "{}: {:.2f}%".format(label, preds[0][i] \* 100)
cv2.putText(output, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7,
	(0, 0, 255), 2)

cv2.imshow("Image", output)
cv2.waitKey(0)

这里就是我们预测函数,训练模型我们已经训练好了!然后走一遍前向传播。结果是这样的!
在这里插入图片描述
这个分类模型主要用了VGG16,然后我们主要是做猫,狗,熊猫三种分类!
在这里插入图片描述

然后我又找了一个猫和老鼠里面的tom猫的照片。然后我们一起来看一下效果!
在这里插入图片描述
检测效果非常nice!!!
然后呢我又用了自己女朋友的照片试了一下!
在这里插入图片描述
果然!!!果然是这样!!!

训练模块
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report#综合结果对比
from keras.models import Sequential
from keras.layers import Dropout
from keras.layers.core import Dense
from keras.optimizers import SGD
from keras import initializers#初始化权重参数
from keras import regularizers#正则化
from my_utils import utils_paths#图像路径的操作
import matplotlib.pyplot as plt
import numpy as np
import argparse
import random
import pickle
import cv2
import os
#--dataset --model --label-bin --plot
# 输入参数
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
	help="path to input dataset of images")
ap.add_argument("-m", "--model", required=True,
	help="path to output trained model")
ap.add_argument("-l", "--label-bin", required=True,
	help="path to output label binarizer")
ap.add_argument("-p", "--plot", required=True,
	help="path to output accuracy/loss plot")
args = vars(ap.parse_args())


print("[INFO] 开始读取数据")
data = []
labels = []

# 拿到图像数据路径,方便后续读取
imagePaths = sorted(list(utils_paths.list_images(args["dataset"])))
random.seed(42)
random.shuffle(imagePaths)

# 遍历读取数据
for imagePath in imagePaths:
	# 读取图像数据,由于使用神经网络,需要给定成一维
	image = cv2.imread(imagePath)
	image = cv2.resize(image, (32, 32)).flatten()
	data.append(image)

	# 读取标签
	label = imagePath.split(os.path.sep)[-2]
	labels.append(label)

# scale图像数据
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)

# 数据集切分
(trainX, testX, trainY, testY) = train_test_split(data,
	labels, test_size=0.25, random_state=42)

# 转换标签,one-hot格式
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)

# 网络模型结构:3072-512-256-3 
model = Sequential()
# kernel\_regularizer=regularizers.l2(0.01)
# keras.initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None)
# initializers.random\_normal
# #model.add(Dropout(0.8))
model.add(Dense(512, input_shape=(3072,), activation="relu" ,kernel_initializer = initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None),kernel_regularizer=regularizers.l2(0.01)))
model.add(Dropout(0.5))
model.add(Dense(256, activation="relu",kernel_initializer = initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None),kernel_regularizer=regularizers.l2(0.01)))
model.add(Dropout(0.5))
model.add(Dense(len(lb.classes_), activation="softmax",kernel_initializer = initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None),kernel_regularizer=regularizers.l2(0.01)))

# 初始化参数
INIT_LR = 0.001
EPOCHS = 200

# 给定损失函数和评估方法
print("[INFO] 准备训练网络...")
opt = SGD(lr=INIT_LR)
model.compile(loss="categorical\_crossentropy", optimizer=opt,
	metrics=["accuracy"])

# 训练网络模型
H = model.fit(trainX, trainY, validation_data=(testX, testY),
	epochs=EPOCHS, batch_size=32)

# 测试网络模型
print("[INFO] 正在评估模型")
predictions = model.predict(testX, batch_size=32)
print(classification_report(testY.argmax(axis=1),
	predictions.argmax(axis=1), target_names=lb.classes_))

# 当训练完成时,绘制结果曲线
N = np.arange(0, EPOCHS)
plt.style.use("ggplot")
plt.figure()
#plt.plot(N[150:], H.history["loss"][150:], label="train\_loss")
#plt.plot(N[150:], H.history["val\_loss"][150:], label="val\_loss")
plt.plot(N[150:], H.history["accuracy"][150:], label="train\_acc")
plt.plot(N[150:], H.history["val\_accuracy"][150:], label="val\_acc")
plt.title("Training Loss and Accuracy (Simple NN)")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.savefig(args["plot"])

# 保存模型到本地
print("[INFO] 正在保存模型")
model.save(args["model"])
f = open(args["label\_bin"], "wb")
f.write(pickle.dumps(lb))
f.close()

这里的卷积过程我们直接用vgg16这个来做了。

VGG
from model_name.simple_vggnet import SimpleVGGNet
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator
from my_utils import utils_paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import random
import pickle
import cv2
import os
import warnings
warnings.filterwarnings("ignore")

# 设置参数
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
	help="path to input dataset of images")
ap.add_argument("-m", "--model", required=True,
	help="path to output trained model")
ap.add_argument("-l", "--label-bin", required=True,
	help="path to output label binarizer")
ap.add_argument("-p", "--plot", required=True,
	help="path to output accuracy/loss plot")
args = vars(ap.parse_args())

# 读取数据和标签
print("[INFO] loading images...")
data = []
labels = []

# 拿到路径
imagePaths = sorted(list(utils_paths.list_images(args["dataset"])))
random.seed(42)
random.shuffle(imagePaths)

# 读取数据
for imagePath in imagePaths:
	image = cv2.imread(imagePath)
	image = cv2.resize(image, (64, 64))
	data.append(image)
	label = imagePath.split(os.path.sep)[-2]
	labels.append(label)

# 预处理
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)

# 数据集切分
(trainX, testX, trainY, testY) = train_test_split(data,
	labels, test_size=0.25, random_state=42)

# 标签转换
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)

# 数据增强

# aug = ImageDataGenerator(rotation\_range=30, width\_shift\_range=0.1,
# height\_shift\_range=0.1, shear\_range=0.2, zoom\_range=0.2,
# horizontal\_flip=True, fill\_mode="nearest")

# 建立卷积神经网络
model = SimpleVGGNet.build(width=64, height=64, depth=3,
	classes=len(lb.classes_))

# 初始化超参数
INIT_LR = 0.01
EPOCHS = 30
BS = 32


![img](https://img-blog.csdnimg.cn/img_convert/559ea9a5ab3d91dce158bc75faf0914b.png)
![img](https://img-blog.csdnimg.cn/img_convert/7476351642e69d09d25b4c98901ad834.png)
![img](https://img-blog.csdnimg.cn/img_convert/4e5c826710d0f3d0f7a9b3055e9bc2ac.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

初始化超参数
INIT_LR = 0.01
EPOCHS = 30
BS = 32


[外链图片转存中...(img-Sj7hQJ6q-1715717767742)]
[外链图片转存中...(img-eZQJs4il-1715717767742)]
[外链图片转存中...(img-eEGKCaKs-1715717767743)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值