网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事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要更加稳定,更加适合。所以我们在计算损失函数的时候一定要进行正则化惩罚项。
这个就是计算损失函数的最终公式。
正则化项在神经网络中的重要作用:
🎁四、神经网络分类器
- Softmax分类器
Softmax分类器简单来说他就是一个多分类,像逻辑回归一样!
Softmax分类器输出的是概率值。 - 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)**