[고양이와 개 인식을 위한 컨볼루션 신경망 사용]------기계 학습(완전한 코드 및 데이터 세트 포함)

최근에 라이징스타 프로그램 파이썬 공식 트랙에 가입했는데 캠프가 열렸을 때 많은 뛰어난 선배님들이 블로거로서의 경험을 공유하는 것을 봤습니다. 그래서 최근 관심을 가지고 있는 인공지능 --- 이미지 인식을 위한 컨볼루션 신경망부터 시작하기로 했습니다. 도움말, 모든 참조 블로그 게시물, 문서, 비디오 및 코드는 기사 끝에 링크됩니다.

이 글의 내용은 다음과 같습니다.

1. 이해하기 쉽고 이해하기 쉬운 컨볼루션

컨볼루션에 관해서는 너무 전문적이고 복잡한 설명이 많으며 종종 헤드가 하나이고 큰 것이 두 개인 경우가 많습니다.
Zhihu 및 Bowen 컨볼루션

1. 컨볼루션의 물리적 의미

첫 번째 클리어:
컨볼루션의 중요한 물리적 의미는 다른 함수(예: 입력 신호)에 대한 함수(예: 단위 응답)의 가중 중첩입니다.
왜 이런 식으로 말합니까?
알려진 x[0] = a, x[1] = b, x[2]=c,
여기에 사진 설명 쓰기
알려진 y[0] = i, y[1] = j, y[2]=k를 참조 하십시오 .
여기에 사진 설명 쓰기
다음 패스 시연 x[n] * y[n]을 찾는 과정과 컨볼루션의 물리적 의미를 밝힙니다.

첫 번째 단계에서 x[n]에 y[0]을 곱하고 위치 0으로 변환합니다.
여기에 사진 설명 쓰기

두 번째 단계에서 x[n]에 y[1]을 곱하고 위치 1로 변환합니다.
여기에 이미지 설명 삽입
세 번째 단계에서 x[n]에 y[2]를 곱하고 위치 2로 변환합니다.
여기에 사진 설명 쓰기
마지막으로 위의 세 이미지는 x[n] * y[n]을 얻기 위해 중첩됩니다.
여기에 사진 설명 쓰기
예, 컨볼루션은 변환 및 중첩에 지나지 않습니다.

2. 컨볼루션의 정의

교과서에서 컨볼루션의 정의는 이렇습니다. 연산으로 이해할 수 있습니다. 초등학생은 덧셈을 먼저 배우고 그 다음에 곱셈을 배운다는 것은 다 아는 사실입니다. 예: 입력 신호) 가중 중첩 .
교과서의 정의를 다시 살펴보자. 체적 적분은 연속적이고 불연속적입니다.

여기에 이미지 설명 삽입

1) 이산 컨벌루션

불연속 신호의 경우 여러 신호의 가중 중첩으로 이해할 수 있습니다.

주사위 던지기의 예

나는 두 개의 주사위를 가지고 있고 둘 다 던져서 다음과 같이 질문합니다: 두 주사위의 합이 4가 될 확률은 얼마입니까?
여기서 문제의 핵심은 두 주사위의 합이 4와 같아야 한다는 것입니다. 롤 광범위한 응용 프로그램 시나리오입니다.

각 주사위의 확률을 표현하면
여기에 이미지 설명 삽입
다음과 같이 두 주사위의 합이 4가 되는 경우는 다음과 같다.
여기에 이미지 설명 삽입
여기에 이미지 설명 삽입
여기에 이미지 설명 삽입
따라서 두 주사위의 합이 4가 될 확률은 다음과 같다.

에프(1)지(3)+에프(2)지(2)+에프(3)지(1)에프(1)지(3)+에프(2)지(2)+에프(3)지( 1)에프 ( 1 ) ( 3 )+에프 ( 2 ) ( 2 )+에프 ( 3 ) ( 1 )

컨볼루션의 정의에 따라 표준 형식으로 작성하면 다음과 같습니다.

( f ∗ g ) ( 4 ) = ∑ m = 1 3 f ( 4 − m ) g ( m ) (f∗g)(4)=∑_{m=1}^3f(4−m)g(m )( 에프g ) ( 4 )=m = 13에프 ( 4-) ( )

2) 이미지 처리의 컨벌루션

여기에 이미지 설명 삽입)
2D 컨볼루션은 매우 간단한 작업입니다.
작은 가중치 행렬로 시작합니다.컨볼루션 커널(커널)시작하려면 2D 입력 데이터를 점진적으로 "스캔"합니다. 컨볼루션 커널이 "슬라이드"하는 동안 가중치 행렬과 스캔한 데이터 행렬(입력 이미지에서)의 곱을 계산한 다음 결과를 하나의 출력 픽셀로 집계합니다.

2. 신경망

인공 뉴런과 신경망은 뇌의 뉴런과 그 연결을 모방합니다.
손실은 순전파로 계산하고, 오류는 역전파로 반환하며, 오류 신호에 따라 각 계층의 가중치를 수정하고 조건이 충족될 때까지 여러 번 반복적으로 업데이트합니다.

여기에 이미지 설명 삽입
1. 신경망은 세 가지 유형의 계층으로 나뉩니다.
입력 계층: 신경망의 가장 왼쪽 계층으로, 뉴런이 훈련 및 관찰해야 할 샘플, 즉 초기 입력 데이터 계층을 입력합니다.
숨겨진 계층: 입력과 출력 사이의 모든 노드로 구성된 계층입니다. 신경망이 데이터, 즉 데이터를 처리하는 계층 간의 복잡한 관계를 학습하는 데 도움이 됩니다.
출력 레이어: 신경망의 마지막 레이어는 최종 결과 출력의 레이어인 처음 두 레이어에서 얻습니다.

2. 전달 함수/활성화 함수 앞의 각 레이어의 입력은 선형 변환 wx + b wx+bwx _+b 뒤에는 시그모이드 함수도 사용하는데, 신경망 구조에서 전달 함수 또는 활성화 함수라고 부른다. Sigmoid 외에도 tanh 및 relu와 같은 활성화 기능이 있습니다. 활성화 함수는 선형 결과를 비선형으로 만듭니다.

3. 전달 함수가 필요한 이유는 간단합니다.활성화 함수가 추가되지 않으면 숨겨진 레이어의 레이어 수에 관계없이 최종 결과는 여전히 원래 입력의 선형 변경이므로 숨겨진 레이어의 한 레이어가 달성할 수 있습니다. 그 결과, 다층 퍼셉트론이 올라가는 의미가 없습니다. 따라서 각 숨겨진 레이어에는 비선형 변화를 제공하는 활성화 기능이 장착됩니다.

3. CNN 합성곱 신경망

일반적인 신경망과 유사하게 CNN의 입력은 이미지 픽셀 정보입니다. 컴퓨터가 보는 그림은 밝음과 어두움을 나타내는 숫자입니다. 컬러 사진은 RGB 3가지 색상으로 구성됩니다.
여기에 이미지 설명 삽입
최상의 모델 매개변수를 얻으려면 CNN 컨벌루션 신경망을 훈련해야 합니다.
여기에 이미지 설명 삽입

1. 입력 데이터:

고양이의 입력 픽셀 정보가 100 * 100 * 3 100*100*3 이라고 가정합니다.1001003 , 여기서 3은 RGB 3색 채널이며 모든 컬러 사진은 3색의 중첩으로 간주될 수 있습니다.

여기에 이미지 설명 삽입
여기에 이미지 설명 삽입
입력 픽셀 정보를 모두 입력으로 사용한다면, 2계층 네트워크의 경우 첫 번째 계층은 3 ∗ 1 0 4 3*10^41 04개의 노드가 있고, 2층에는 1000개의 노드가 있고, 전체 연결을 고려하면 계산량이3 ∗ 1 0 7 3*10^7에1 07 . 다중 계층 네트워크가 있는 경우 계산량이 기하급수적으로 증가합니다.

일부
패턴은 전체 이미지보다 훨씬 작으며 패턴을 발견하기 위해 전체 이미지를 볼 필요는 없지만 더 적은 매개변수로 작은 영역에 연결할 필요가 있습니다.
예를 들어, 고양이는 일반적으로 뾰족한 귀가 특징입니다. 우리는 "고양이 귀" 감지기를 실행하기만 하면 됩니다.
여기에 이미지 설명 삽입
동시에 요약
여기에 이미지 설명 삽입하자면
여기에 이미지 설명 삽입
CNN 모델을 설계할 수 있습니다.

2. 모델

여기에 이미지 설명 삽입)

여기에 이미지 설명 삽입)

3. 컨볼루션 레이어

1) 컨볼루션 커널:

컨볼루션 레이어의 컨볼루션 커널은 학습이 필요한 매개변수이며 다른 컨볼루션 커널은 다른 효과를 갖습니다. 다음과 같이: 가장자리 감지 또는 선명화 등
여기에 이미지 설명 삽입

여기에 이미지 설명 삽입
위와 같이 원본 이미지는 8 ∗ 8 8*888 픽셀, 컨볼루션 결과는6 ∗ 6 6*666 픽셀. 그런 다음 원본 사진과 동일한 픽셀을 얻기 위해 테두리를 처리해야 합니다.
구체적인 방법은 스캔할 데이터 매트릭스 주위에 0을 추가하는 것이며 추가할 원의 수는 상황에 따라 다릅니다. 또는 컨볼루션 이동의 단계 크기를 변경합니다.

2) 패딩: 처리 경계

여기에 이미지 설명 삽입

3) Stride: 컨볼루션 커널 이동의 단계 크기

여기에 이미지 설명 삽입

4. 최대 풀링 레이어

위의 경계 및 단계 크기를 변경하는 방법 외에도 풀링 레이어 부분에서도 방법을 찾을 수 있습니다. 이름에서 알 수 있듯이 각 분수의 최대값을 출력으로 취하는 최대 풀링 계층을 가질 수 있습니다.
여기에 이미지 설명 삽입

5、플래튼

컨볼루션 이후의 새로운 이미지 데이터는 평탄화되어 완전히 연결된 네트워크에 입력됩니다.
여기에 이미지 설명 삽입

요약하다:

1. 컨볼루션 신경망의 주요 설계 아이디어는 그림의 특성을 더 잘 활용하는 것입니다.

●사진의 패턴이 사진보다 훨씬 작습니다.

● 사진의 패턴이 이미지의 다른 영역에 나타납니다.

●크기 조정은 사진의 개체에 영향을 주지 않습니다.

2. 컨볼루션 레이어는 그림의 특징을 스캔하는 것입니다.

3. 최대 풀링 계층은 그림을 스케일링하고 매개변수를 줄이는 것입니다.

4. 다중 컨벌루션 및 풀링 후 flatten을 통해 완전히 연결된 레이어를 연결합니다.

4. 고양이, 강아지 인식코드 구현

코드는 1) 모델 교육, 2) 분류 효과 테스트의 두 부분으로 나뉩니다.

1. 코드

1) 교육 모델

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@File :CNN_train.py
"""
import sys
from matplotlib import pyplot
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPool2D
from keras.layers import Dense
from keras.layers import Flatten
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
import tensorflow as tf
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
 
def define_cnn_model():
    # 使用Sequential序列模型
    model = Sequential()
    # 卷积层
    model.add(Conv2D(32,(3,3),activation="relu",padding="same",input_shape=(200,200,3))) 
    # 添加一个卷积层,第一个参数32是卷积核的数量,第二个是卷积核的规格,(3,3)即为3*3的,3是颜色通道个数。第三个参数relu是激活函数类型,第四个是same边缘的处理办法,第五个因为第一层即为卷积层,要定义输入图片的规格(200,200,3)即为200*200,3说明是彩色图片。 
    # 最大池化层
    model.add(MaxPool2D((2,2)))  # 池化窗格  (2,2)说明每2*2化作一个窗格。
    # Flatten层
    model.add(Flatten())   # 再添加一个Flatten层,将池化后的结果展开。
    # 全连接层
    model.add(Dense(128,activation="relu"))  # 再添加一个全连接层,第一个参数是神经元个数,第二个参数是激活函数的类型;
    model.add(Dense(1,activation="sigmoid"))  # 最后再添加一个全连接层输出结果,注意我们的结果需判断猫狗就行,因此一个神经元就行。二分类,所以只需要一个神经元就够了。
    # 编译模型
    opt = SGD(lr= 0.001,momentum=0.9)  # 随机梯度,最后用随机梯度编译模型。
    model.compile(optimizer=opt,loss="binary_crossentropy",metrics=["accuracy"])
    return model

def train_cnn_model():
    # 实例化模型
    model = define_cnn_model()
    # 创建图片生成器
    datagen = ImageDataGenerator(rescale=1.0/255.0)
    train_it = datagen.flow_from_directory(
        "./ma1ogo3ushu4ju4ji2/dogs_cats/data/train/",
        class_mode="binary",
        batch_size=64,
        target_size=(200, 200))  # batch_size:一次拿出多少张照片 targe_size:将图片缩放到一定比例
    # 训练模型
    model.fit_generator(train_it,
                        steps_per_epoch=len(train_it),
                        epochs=20,                   #  !!!!!!!!!!!!20次结果较准确
                        verbose=1)
    model.save("my_model.h5")
train_cnn_model()
#首先调用define_cnn_model(),紧接着创建图片生成器:这个作用就是把文件夹中的图片传入模型中训练。里面的参数batch_size是规定一次只能传入64张图片,这样可以有效地避免内存的问题。训练模型中一个重要参数epochs,这里设置为20,说明传入的图片他要学习20次。比如,这里我总共传入了2500张图片,它学习了20次,也就是50000张图片。这样的重复学习,可以有效提高进度,但是当你值调整比较大时,会非常耗时。最后将训练好的模型保存到项目文件夹下。

2) 검사 분류 효과

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@File    :CNN_test.py
"""
 
import os,random
import matplotlib.pyplot as plt
from keras.models import load_model
from matplotlib.pyplot import imshow
import numpy as np
from PIL import Image
model_path = "my_model.h5"
model = load_model(model_path)
import pylab
plt.rcParams['font.sans-serif']=['SimHei']
def read_random_image():
    folder = r"./ma1ogo3ushu4ju4ji2/dogs_cats/data/test/"
    file_path = folder + random.choice(os.listdir(folder))
    pil_im = Image.open(file_path, 'r')
    return pil_im
 
def get_predict(pil_im,model):
    # 首先更改图片的大小
    name = ''
    pil_im = pil_im.resize((200,200))
    # 将格式转为numpy array格式
    array_im = np.asarray(pil_im)
    # array_im = array_im.resize((4,4))
    array_im = array_im[np.newaxis,:]    # 注意上一行的array_im 是一个三维数组,不符合运行规范,这里要将其转化为四位数组,否则会报错!
    #对图像检测
    result = model.predict([[array_im]])
    if result[0][0]>0.5:
        name = "它是狗!"
        print("预测结果是:狗")
    else:
        name = "它是猫!"
        print("预测结果是:猫")
    return name
pil_im =read_random_image()
imshow(np.asarray(pil_im))
plt.title(get_predict(pil_im,model))
pylab.show()

2. 코드 설명

1) 하드

여기에 이미지 설명 삽입

2) 순차적 모델

여기에 이미지 설명 삽입 여기에 이미지 설명 삽입

import keras
from keras import layers
model = keras.Sequential()  #建立模型
model.add(layers.Dense(20,activation="relu",input_shape=(10,))) # 加了一个全连接层 (神经元数量,激活函数,输入的参数值数量:10个参数)
model.add(layers.Dense(20,activation="relu"))  # 再加一个全连接层
model.add(layers.Dense(10,activation="softmax")) # 同上
model.fit(x,y,epochs=10,batch_size=32)  #模型训练: x是图片,y是图形标签 epochs:每张图片看、训练10遍 batch_size:一次只传入32张图片
keras. Sequential() 建立函数

model.add() 添加层

model.fit() 训练模型

3) 컨브2D

keras.layers.Conv2D(filters,kernel_size,strides=(1,1),padding="valid",data_formt=None))
filters:整数,输出空间的维度,卷积核的数量

kernel_size:一个整数,或者2个整数代表的元组或列表,指明2D卷积窗口的宽度和高度,可以是一个整数,为所有空间维度指定相同的值。

strides:一个整数,或者2个整数代表的元组或列表,指明卷积沿宽度和高度方向的步长。可以是一个整数,为所有空间维度指定相同的值。

padding:"valid"或者"same",大小写敏感,用于边缘处理部分。

4) 맥스풀링2D

keras.layers.MaxPooling2D(pool_size=(2,2),strides=None,padding="valid",data_format =None)
pool_size:整数,或者2个整数表示的元组,沿(垂直,水平)方向缩小比例的因数。(2,2)会把输入张量的两个维度都缩小一半。如果只使用一个整数,那么两个维度都会使用同样的窗口长度。

strides:整数,2个整数表示的元组,或者是None。表示步长值。如果是None,那么默认值是pool_size。

padding:"valid"或者“same"

3. 결과 분석

대부분의 경우는 여전히 정확하게 식별할 수 있음을 알 수 있습니다.
여기에 이미지 설명 삽입여기에 이미지 설명 삽입여기에 이미지 설명 삽입여기에 이미지 설명 삽입

하지만 개별적으로 인식이 잘못된 경우도 있는데, 훈련된 CNN_test.py의 맨 아래에서 네 번째 라인인 epoch의 반복 횟수를 늘리면 정확도가 향상될 수 있음은 확실합니다.
예를 들어:

여기에 이미지 설명 삽입여기에 이미지 설명 삽입여기에 이미지 설명 삽입

데이터 세트 소스:

고양이와 개의 데이터 세트
여기에 이미지 설명 삽입

참조 문서:

합성곱 신경망(CNN) 기반 고양이와 개 인식을
위한 합성곱에 대한 가장 이해하기 쉬운 설명

참조 비디오:

교육 비디오

마지막으로 공유해주신 선배님들께 감사의 인사를 전합니다. 이 글을 먼저 여기에 쓰겠습니다. 댓글과 수정은 환영합니다!

Supongo que te gusta

Origin blog.csdn.net/weixin_47296493/article/details/129868596
Recomendado
Clasificación