목차
1. CNN(Convolutional Neural Network)과 FCN(Fully Connected Network)의 유사점과 차이점
2. 신경망 순방향 및 역방향 전파 알고리즘의 최적 반복 공식
시리즈 기사 디렉토리
이 시리즈의 블로그는 기계 학습의 개념, 원리 및 코드 실행에 초점을 맞추고 지루한 수학적 파생을 포함하지 않습니다(질문이 있는 경우 의견 영역에서 토론하고 지적하거나 개인 메시지로 직접 연락하십시오). .
누구나 원리를 이해하고 코드를 재생산하는 과정은 복사가 가능합니다 ( 딥러닝은 이해하지 못하지만 )! ! !
1장 기계 학습 - PCA(주성분 분석) 및 얼굴 인식
Chapter 2 머신러닝 - LDA(Linear Discriminant Analysis) 및 얼굴 인식_@李忆如的博客-CSDN博客
3장 기계 학습 - LR(선형 회귀), LRC(선형 회귀 분류) 및 얼굴 인식_@李梦如的博客
Chapter 4 기계 학습 - SVM(Support Vector Machine) 및 얼굴 인식_@李梦如的博客
5장 기계 학습 - K-평균(클러스터링) 및 얼굴 인식
6장 기계 학습 - 실제 심층 신경망
개요
이 블로그는 주로 심층 신경망(FNC, CNN, BP 등) 알고리즘의 개념과 원리 , 관련 분석 및 도출을 소개하고, FCN과 CNN의 유사점과 차이점을 비교하고, 신경망 순방향 및 역전파 알고리즘. 그리고 심층 신경망 알고리즘을 적용하여 실제 문제를 해결합니다(예: 얼굴 인식, 필기 인식, 이미지 분류). 또한 기존 신경망의 단점을 감안하여 다양한 측면과 각도에서 최적화된 새로운 심층신경망 알고리즘을 설계하였다(데이터셋 및 파이썬 코드 첨부 ).
1. CNN(Convolutional Neural Network) 과 FCN(Fully Connected Network) 의 유사점과 차이점
1. 유사점
① 유사한 구조: 두 신경망은 노드의 레이어를 통해 구성되며 각 노드는 뉴런이며 노드 사이에 일부 또는 두 개의 에지가 있습니다.
②프로세스는 유사하다: 컨볼루션 신경망의 입력 및 출력과 훈련 프로세스는 기본적으로 완전히 연결된 신경망과 동일합니다.이미지 분류를 열로 사용하여 컨볼루션 신경망의 입력 레이어는 원본 이미지입니다. 이미지 및 각 출력 레이어 노드는 서로 다른 범주의 신뢰도를 나타냅니다. 이는 완전히 연결된 신경망의 입력 및 출력과 일치합니다. 유사하게 완전 연결 신경망의 손실 함수와 매개변수의 최적화 과정은 컨볼루션 신경망에도 적용할 수 있습니다.
2. 차이점
둘 사이의 주요 차이점은 신경망의 인접한 두 계층이 연결되는 방식 입니다 . 완전히 연결된 신경망에서는 두 개의 인접한 레이어 사이의 노드가 에지로 연결되는 반면, 컨벌루션 신경망의 경우 인접한 두 레이어 사이에 일부 노드만 연결됩니다. 위와 같은 둘의 차이로 인해 Fully Connected Neural Network는 이미지 데이터를 잘 처리할 수 없습니다(데이터 및 네트워크 레이어의 수가 증가할수록 매개변수의 수가 폭발적으로 증가하고 계산 속도가 느려지며 Over-fitting 문제가 발생하기 쉽습니다.) 발생), 컨볼루션 신경망은 이러한 단점을 극복합니다. 두 알고리즘의 차이점과 흐름은 대략 다음과 같습니다.
2. 신경망 순방향 및 역방향 전파 알고리즘의 최적 반복 공식
BP 그래프 모델:
네트워크의 단일 활성화 단위:
팁 : 위의 그림은 바이어스 항목 b 를 포함하는 숨겨진 레이어의 활성화 단위를 정의합니다 . 관련 동작은 그림과 같다 심볼의 우측 상단은 네트워크에서 단위의 레이어로 표시 코드 구현과 결합하면 일반적으로 네트워크 활성화 단위 사이의 가중치는 이전 레이어의 단위로 저장된다 .
손실 함수 정의:
특정 순방향 및 역방향 전파 알고리즘의 최적화된 반복 공식의 유도는 다음과 같이 볼 수 있습니다.
신경망의 전방 및 후방 전파 유도 및 구현 - liangxinGao's Blog - CSDN Blog
신경망의 정방향 전파 및 역전파에 대해 자세히 설명(처음부터 파생) - Maples,'s Blog - CSDN Blog
3. 심층신경망 알고리즘의 적용
1. 얼굴 인식
Pycharm에서 CNN 기반의 심층 신경망 모델은 ORL 데이터 세트를 기반으로 구축되어 얼굴 인식에 사용됩니다.코드는 다음과 같습니다.
1.1 데이터 가져오기
import numpy
import pandas
from PIL import Image
from keras import backend as K
from keras.utils import np_utils
"""
加载图像数据的函数,dataset_path即图像olivettifaces的路径
加载olivettifaces后,划分为train_data,valid_data,test_data三个数据集
函数返回train_data,valid_data,test_data以及对应的label
"""
# 400个样本,40个人,每人10张样本图。每张样本图高57*宽47,需要2679个像素点。每个像素点做了归一化处理
def load_data(dataset_path):
img = Image.open(dataset_path)
img_ndarray = numpy.asarray(img, dtype='float64') / 256
print(img_ndarray.shape)
faces = numpy.empty((400,57,47))
for row in range(20):
for column in range(20):
faces[row * 20 + column] = img_ndarray[row * 57:(row + 1) * 57, column * 47:(column + 1) * 47]
# 设置400个样本图的标签
label = numpy.empty(400)
for i in range(40):
label[i * 10:i * 10 + 10] = i
label = label.astype(numpy.int)
label = np_utils.to_categorical(label, 40) # 将40分类类标号转化为one-hot编码
# 分成训练集、验证集、测试集,大小如下
train_data = numpy.empty((320, 57,47)) # 320个训练样本
train_label = numpy.empty((320,40)) # 320个训练样本,每个样本40个输出概率
valid_data = numpy.empty((40, 57,47)) # 40个验证样本
valid_label = numpy.empty((40,40)) # 40个验证样本,每个样本40个输出概率
test_data = numpy.empty((40, 57,47)) # 40个测试样本
test_label = numpy.empty((40,40)) # 40个测试样本,每个样本40个输出概率
for i in range(40):
train_data[i * 8:i * 8 + 8] = faces[i * 10:i * 10 + 8]
train_label[i * 8:i * 8 + 8] = label[i * 10:i * 10 + 8]
valid_data[i] = faces[i * 10 + 8]
valid_label[i] = label[i * 10 + 8]
test_data[i] = faces[i * 10 + 9]
test_label[i] = label[i * 10 + 9]
return [(train_data, train_label), (valid_data, valid_label),(test_data, test_label)]
if __name__ == '__main__':
[(train_data, train_label), (valid_data, valid_label), (test_data, test_label)] = load_data('olivettifaces.gif')
oneimg = train_data[0]*256
print(oneimg)
im = Image.fromarray(oneimg)
im.show()
1.2 모델 구성 및 사용
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, AveragePooling2D
from PIL import Image
import FaceData
# 全局变量
batch_size = 128 # 批处理样本数量
nb_classes = 40 # 分类数目
epochs = 23000 # 迭代次数
img_rows, img_cols = 57, 47 # 输入图片样本的宽高
nb_filters = 32 # 卷积核的个数
pool_size = (2, 2) # 池化层的大小
kernel_size = (5, 5) # 卷积核的大小
input_shape = (img_rows, img_cols, 1) # 输入图片的维度
[(X_train, Y_train), (X_valid, Y_valid), (X_test, Y_test)] = FaceData.load_data('olivettifaces.gif')
X_train = X_train[:, :, :, np.newaxis] # 添加一个维度,代表图片通道。这样数据集共4个维度,样本个数、宽度、高度、通道数
X_valid = X_valid[:, :, :, np.newaxis] # 添加一个维度,代表图片通道。这样数据集共4个维度,样本个数、宽度、高度、通道数
X_test = X_test[:, :, :, np.newaxis] # 添加一个维度,代表图片通道。这样数据集共4个维度,样本个数、宽度、高度、通道数
print('样本数据集的维度:', X_train.shape, Y_train.shape)
print('测试数据集的维度:', X_test.shape, Y_test.shape)
# 构建模型
model = Sequential()
model.add(Conv2D(6, kernel_size, input_shape=input_shape, strides=1)) # 卷积层1
model.add(AveragePooling2D(pool_size=pool_size, strides=2)) # 池化层
model.add(Conv2D(12, kernel_size, strides=1)) # 卷积层2
model.add(AveragePooling2D(pool_size=pool_size, strides=2)) # 池化层
model.add(Flatten()) # 拉成一维数据
model.add(Dense(nb_classes)) # 全连接层2
model.add(Activation('sigmoid')) # sigmoid评分
# 编译模型
model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy'])
# 训练模型
model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X_valid, Y_valid))
# 评估模型
score = model.evaluate(X_test, Y_test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
y_pred = model.predict(X_test)
y_pred = y_pred.argmax(axis=1) # 获取概率最大的分类,获取每行最大值所在的列
for i in range(len(y_pred)):
oneimg = X_test[i, :, :, 0] * 256
im = Image.fromarray(oneimg)
# im.show()
print('第%d个人识别为第%d个人' % (i, y_pred[i]))
1.3 결과 및 분석
Pycharm에서는 ORL 데이터셋을 기반으로 CNN 기반의 심층신경망 모델을 구축하여 얼굴인식에 사용하였으며, 반복 횟수 epoch에 따른 손실과 얼굴인식률의 관계를 각각 기록하였다. :
분석 : ORL 데이터셋 하에서 반복 횟수가 증가함에 따라 CNN 심층 신경망 모델의 효과가 점차 향상되어 손실률이 지속적으로 감소하고, 얼굴 인식률이 지속적으로 증가함(후 99.37%까지) 20,000회 반복) 대부분의 알고리즘보다 우수합니다.
2. 필기 인식
Pycharm에서 Mnist 데이터 세트는 필기 숫자 인식을 위한 BP 심층 신경망 모델을 기반으로 구축되며 코드는 다음과 같습니다.
2.1 BP 신경망 기반 필기 숫자 인식 코드
import numpy as np
from sklearn.datasets import load_digits
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt
# 载入数据
digits = load_digits()
# 显示图片
for i in range(min(digits.images.shape[0], 2)):
plt.imshow(digits.images[i], cmap='gray')
plt.show()
# 数据
X = digits.data
# 标签
y = digits.target
# 定义一个神经网络,结构,64-100-
# 定义输入层到隐藏层之间的权值矩阵
V = np.random.random((64, 100)) * 2 - 1
# 定义隐藏层到输出层之间的权值矩阵
W = np.random.random((100, 10)) * 2 - 1
# 数据切分
# 1/4为测试集,3/4为训练集
X_train, X_test, y_train, y_test = train_test_split(X, y)
# 标签二值化
# 0 -> 1000000000
# 3 -> 0003000000
# 9 -> 0000000001
labels_train = LabelBinarizer().fit_transform(y_train)
# 激活函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 激活函数的导数
def dsigmoid(x):
return x * (1 - x)
# 训练模型
def train(X, y, steps=10000, lr=0.011):
global V, W
for n in range(steps + 1):
# 随机选取一个数据
i = np.random.randint(X.shape[0])
# 获取一个数据
x = X[i]
x = np.atleast_2d(x)
# BP算法公式
# 计算隐藏层的输出
L1 = sigmoid(np.dot(x, V))
# 计算输出层的输出
L2 = sigmoid(np.dot(L1, W))
# 计算L2_delta,L1_delta
L2_delta = (y[i] - L2) * dsigmoid(L2)
L1_delta = L2_delta.dot(W.T) * dsigmoid(L1)
# 更新权值
W += lr * L1.T.dot(L2_delta)
V += lr * x.T.dot(L1_delta)
# 每训练1000次预测一次准确率
if n % 1000 == 0:
output = predict(X_test)
predictions = np.argmax(output, axis=1)
acc = np.mean(np.equal(predictions, y_test))
dW = L1.T.dot(L2_delta)
dV = x.T.dot(L1_delta)
gradient = np.sum([np.sqrt(np.sum(np.square(j))) for j in [dW, dV]])
print('steps', n, 'accuracy', acc, 'gradient', gradient)
# print(classification_report(predictions,y_test))
def predict(x):
# 计算隐藏层的输出
L1 = sigmoid(np.dot(x, V))
# 计算输出层的输出
L2 = sigmoid(np.dot(L1, W))
return L2
# 开始训练
train(X_train, labels_train, 20000, lr=0.11)
train(X_train, labels_train, 20000, lr=0.011)
# 训练后结果对比
output = predict(X_test)
predictions = np.argmax(output, axis=1)
acc = np.mean(np.equal(predictions, y_test))
print('accuracy', acc)
print(classification_report(predictions, y_test, digits=4))
2.2 결과 및 분석
Pycharm에서는 BP 심층 신경망 모델을 기반으로 Mnist 데이터셋을 구축하여 필기 숫자 인식에 사용하고, 인식률과 반복 에포크 수의 관계를 기록하고 그 결과는 다음 차트와 같습니다.
분석 : Mnist 데이터셋 하에서는 반복 횟수가 증가할수록 BP 심층신경망 모델의 효과가 점차 향상되어 인식률이 계속해서 증가하는 것으로 나타났다(기본적으로 10,000회 반복 후 약 96%로 안정적임).
3. 이미지 분류
이 부분은 주로 MindSpore(CPU) 버전을 사용하여 Fine-Tuning을 통해 고양이와 개 분류 모델(Huawei Cloud 실험)을 훈련합니다.전체 실험 프로세스는 다음과 같습니다.
3.1 모델 구축 과정 및 결과
모델 구축의 프로세스와 결과는 그림에 나와 있습니다.
3.2 초기 사전 훈련 분류
초기 사전 훈련 분류 결과는 다음과 같습니다.
분석 : context_device_init 함수는 훈련 환경을 초기화한 다음 네트워크 구조를 정의하고 CKPT 매개변수를 읽고 네트워크 하이퍼 매개변수를 구성합니다. 그러나 pre-training에서 backbone의 parameter를 읽어서 직접 예측을 하고 그 결과를 보여주는데 그 결과를 보면 예측 정확도가 미흡하다는 것을 알 수 있다.
3.3 미세 조정 훈련
미세 조정 훈련 후 결과는 다음과 같습니다.
분석 : 사전 학습 후 옵티마이저, 학습률, 손실 함수를 정의합니다. 공식 미세 조정 훈련 후 원본 데이터 세트 파일에 여러 npy 파일이 생성됩니다.설문지는 주로 훈련 과정에서 관련 변수와 레이블을 저장합니다.그 후 네트워크는 로컬 훈련을 완료하고 성공적으로 MindIR 모델을 얻었습니다. 위의 그림에서 볼 수 있듯이 미세 조정 훈련 후 정확도가 증가하고 분류가 정확하며 모델이 성공적으로 구축됩니다.
4. 혁신적인 신경망 알고리즘 설계
① 기존 CNN의 단점: 과대적합 결과, 감독 문제에서의 성능 저하, 기능 이해도 저하, 해석 가능성 저하
② 최적화 방향 : 데이터 처리, 컨볼루션 방식 설계, 아키텍처 설계, 활성함수 선택원리, 옵티마이저 선택 등
③ 최적화 지표: 모델 정확도, 학습 속도, 메모리 사용량
④ 혁신적인 신경망 알고리즘 프로세스에 대한 간략한 설명:
하나. 데이터 정리 및 향상 : 데이터 선택 및 정리가 적절하지 않으면 얻은 결과가 종종 과적합된 것처럼 보입니다. 다양한 데이터 향상 방법을 사용하여 애플리케이션 시나리오에 따라 데이터 품질을 향상함과 동시에 데이터 왜곡/불균형에 대해 오버 샘플링, 다운 샘플링, SMOTE, 통합 학습, 범주 가중치, 학습 방법 변경 등을 추가하거나 데이터를 사용할 수 있습니다. 직접 로드 배치 교육.
둘. 절묘한 컨볼루션 디자인 : MobileNets(깊이 분리 컨볼루션), XNOR-Net(이진 컨볼루션), ShuffleNet(사용하는 포인트 그룹 컨볼루션 및 채널 무작위화), 네트워크 가지치기(CNN의 일부 가중치 제거)
삼. 컨볼루션 커널 요소(옵트인) : 일반적으로 더 큰 컨볼루션 커널은 더 높은 정확도를 갖지만 훈련 속도는 더 느려지고 더 많은 메모리를 소비하며 더 큰 컨볼루션 커널은 네트워크 일반화로 이어집니다.
팁: 컨볼루션 커널의 가중치 사이에 공백을 사용하십시오. 이를 통해 네트워크는 매개변수의 양을 늘리지 않고도 수용 영역을 확장할 수 있으므로 메모리 소비가 증가하지 않습니다. 이 접근 방식은 약간의 속도 절충으로 네트워크 정확도를 높이는 것으로 나타났습니다.
넷. 네트워크 크기(너비 / 깊이) 의 합리적인 확장 : GPU가 병렬로 처리되기 때문에 깊이를 늘리는 것보다 너비를 늘리는 것이 GPU에 더 친숙합니다.또한 많은 연구에서 네트워크를 넓히는 것이 네트워크를 깊게 하는 것보다 훈련하기 쉽다는 것을 보여주었습니다. . 그러나 너비와 깊이가 가져오는 이점은 한계 효과에 의해 제한되며, 각 레이어의 너비가 클수록 레이어 너비를 늘려도 모델 성능 향상이 작아지므로 합리적인 선택이 필요합니다.
다섯. 활성화 함수 선택 최적화 : 엔지니어링 경험에 따르면 일반적으로 ReLU를 사용하면 처음에 즉시 좋은 결과를 얻을 수 있지만 ReLU가 좋은 결과를 얻을 수 없는 경우 Sigmoid 함수로 대체할 수 있습니다. 정확도를 향상시키기 위해 모델 및 기타 부품을 조정하십시오. 좋은 결과를 얻을 수 없다면 ELU, PReLU, Sigmoid 또는 LeakyReLU와 같은 활성화 함수를 사용해 볼 수 있습니다.
육. 옵티마이저 선택 최적화 : 이미지 분류 문제에 적용된 간단한 CNN의 경우 다양한 옵티마이저를 사용하여 학습 속도를 높이는 효과는 다음과 같습니다.
분석 : 옵티마이저를 합리적으로 선택하고 좋은 결과를 얻으면 모델의 다른 하이퍼파라미터를 튜닝합니다. 학습 속도를 너무 높게 설정하지 않도록 주의하십시오. 앞쪽에는 빠른 옵티마이저를 사용하여 낮은 학습 효율을 설정하고, 훈련 후반에는 느린 옵티마이저를 선택하여 결합된 옵티마이저를 수행하는 등 조합하여 사용할 수도 있습니다.
5. 기타
1. 데이터 세트 및 리소스
이 실험에 사용된 데이터 세트: ORL5646, Mnist, 고양이 및 개 데이터 세트.
일반적으로 사용되는 얼굴 데이터 세트는 다음과 같습니다 (성매매 하지 마세요 ㅎㅎ)
링크: https://pan.baidu.com/s/12Le0mKEquGMgh5fhNagZGw
추출 코드: yrnb
심층 신경망 애플리케이션 전체 코드 및 필수 데이터 세트: Li Yiru/Yiru의 머신 러닝 - Gitee.com
2. 참고문헌
2. 신경망의 정방향 및 역방향 전파 유도 및 구현_liangxinGao의 블로그-CSDN 블로그
3. 마스터에서 keras/Face_Recognition · data-infra/keras · GitHub
4. 신경망이 손글씨체 인식을 실현하다_myourdream2의 블로그-CSDN 블로그_신경망 글꼴 인식
5. "인공지능 입문" 딥러닝 실험 매뉴얼
6. CNN(Convolutional Neural Network) - 최적화 가이드 - Zhihu(zhihu.com)
요약하다
심층신경망은 딥러닝 분야에서 대중적이고 중요한 연구 분야로, 대부분의 알고리즘(CNN, BP 등)은 기계학습 및 패턴인식 분야의 실제 업무에서 다양한 고전 알고리즘을 뛰어넘는 우수한 성능을 보인다. 또한 심층 신경망은 빅 데이터 작업 처리 성능이 우수하고 발전 가능성이 큽니다. 그러나 동시에 여전히 많은 결함이 있습니다. 그 중 첫 번째는 모델의 선택 및 구성뿐만 아니라 딥 러닝 방법의 일반적인 문제인 해석 가능성 및 견고성 문제입니다. 이는 실험 결과에 큰 영향을 미치므로 심층 신경망을 어떻게 잘 활용하고 모델을 선택하고 알고리즘을 최적화하느냐는 딥러닝 분야에서 매우 중요한 문제입니다.