Làm giàu dữ liệu

Một phần của tài liệu Nghiên cứu và ứng dụng machine vision phát hiện sản phẩm lỗi trong công nghiệp (Trang 86)

4. Đề nghị cho bảo vệ hay không?

5.2 Làm giàu dữ liệu

Mô hình học sâu có xu hướng quá khớp (overfitting) với tập dữ liệu nhỏ vì có quá ít ví dụ để đào tạo, dẫn đến một mô hình có hiệu suất kém. Tăng dữ liệu là một kỹ thuật để tạo ra nhiều trường hợp dữ liệu huấn luyện hơn bằng cách tạo các mẫu mới thông qua chuyển đổi ngẫu nhiên các dữ liệu hiện có. Phương pháp này giúp tăng kích thước của tập huấn luyện. Các phép biến đổi phổ biến là lật ngang, điều chỉnh độ sáng được minh họa trong Hình 6.5 Ngoài ra, việc tăng dữ liệu chỉ được thực hiện trên dữ liệu huấn luyện, không phải xác thực hoặc tập kiểm tra.

Hình 5.4 Làm giàu dữ liệu bằng cách thay đổi độ sáng

5.3 Quá trình đào tạo

Dữ liệu được lưu trữ sau đó được sao chép vào máy tính, được trang bị Core-i5 9300H, 2.4GHz, Ram 8GB, tôi đã đào tạo mạng để tăng tốc độ đào tạo. Với mô hình phân loại, tôi chia tập dữ liệu thành hai tập con: tập huấn luyện (85%) và tập kiểm thử (15%). Tập dữ liệu đào tạo chứa 900 mẫu, bộ kiểm tra chứa 150 mẫu.

Tôi đã sử dụng app Visual Studio Code để viết chương trình huấn luyện mạng thần kinh nhân tạo cho mô hình nhận dạng. Đây là một ứng dụng rất dễ dùng và giúp đơn giản việc debug rất nhiều.

Hình 5.5 Giao diện lập trình với Visual Studio Code

Trước khi chạy huấn luyện mô hình thì chúng ta cần thiết lập những thông số sau: Image size = 224: Mạng VGG16 yêu cầu kích thước ảnh đầu vào là 224 x 224. Batchsize: 8. Đây là số lượng mẫu dữ liệu trong một batch.

Hình 5.6 Thiết lập batchsize và imagesize

Optimizer: RMSprop. Đây là một phương thức tối ưu việc cập nhật các trọng số của mô hình.

Number of Epochs : 50. Đây là số lần thông qua toàn bộ tập dữ liệu đào tạo. Learning rate: 1e-5. Đây là một siêu tham số kiểm soát trọng số của mạng, điều chỉnh độ mất mát.

Hình 5.7 Khai báo các thông số cần thiết

Hình 5.8 Mô hình đang được huấn luyện

Hình 5.10 Thay đổi độ chính xác trong suốt quá trình đào tạo

5.4 Kết quả thực nghiệm

Sau khi được đào tạo trên máy tính, mô hình đã được sao chép trở lại Jetson Nano. Sau đó được đưa vào hệ thống Machine Vision được thiết kế từ trước và chạy đồng thời cùng PLC, hệ thống bang tải và cơ cấu chấp hành, sau khi cảm biến phát hiện được vật thì khoảng thời gian từ lúc camera chụp hình đến lúc xử lý xong ảnh là ~1.5-2s/sp. Do camera và máy tính nhúng không phải dùng cho công nghiệp nên tốc độ xử lý sẽ không được lý tưởng. Hình ảnh thử nghiệm cho dự đoán của mô hình có thể nhìn thấy trong hình 5.12.

Mô hình được đào tạo đã có thể đạt được một độ chính xác gần như tuyệt đối, hệ thống có thể hoạt động đúng với yêu cầu đặt ra là phát hiện sản phẩm lỗi bất kể vết móp nằm ở phía nào của lon đi nữa.

Hình 5.12 Kết quả thực nghiệm: Trên cùng là hình ảnh và phía dưới là đầu ra sau thông qua chức năng Softmax của mô hình. (a) Bình thường, (b) Móp đầu, (c) Móp

trên, (d) Móp giữa

Chương 6

KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN

Trong đề tài này, tôi đã trình bày một hệ thống Machine Vision phát hiện sản phẩm lỗi dựa trên phương pháp xử lý ảnh và công nghệ AI tiên tiến. Công việc này giải quyết rất nhiều vấn đề có trong sản xuất mà không cần đến giác quan của con người. Có hai phương pháp đã được sử dụng trong luận án này: Xử lý tín hiệu ảnh và mô hình Phát hiện đối tượng (độ chính xác đào tạo: 98%). Tôi quyết định kết hợp hai phương pháp này lại với nhau để tăng độ chính xác, đồng thời giảm đáng kể thời gian xử lý từ lúc chụp đến lúc xuất tín hiệu.

Kết quả đáng khích lệ cho thấy mô hình mạng thần kinh tích chập hoạt động rất tốt với việc xử lý dữ liệu trong thời gian thực. Bất chấp sự phức tạp của mạng lưới thần kinh, các nền tảng điện toán nhúng như Raspberry Pi hay NVIDIA Jetson Nano Kit đủ mạnh để hỗ trợ tầm nhìn và các ứng dụng điều khiển thời gian thực dựa trên học tập sâu. Do sự phức tạp của mạng, mỗi máy tính nhúng chỉ có thể xử lý một mô hình, vì vậy nếu chúng ta cần thêm một mô hình để xử lý một tác vụ khác thì sẽ cần đến một chiếc máy tính nhúng thứ hai.

Vấn đề chúng quan sát thấy trong việc kiểm tra mạng là độ trễ camera. Nó được định nghĩa là khoảng thời gian từ khi cảm biến phát hiện vật đến lúc máy tính thực sự đọc dữ liệu hình ảnh được số hóa. Thật không may, thời gian này có thể dài đáng kể tùy thuộc vào máy ảnh và hiệu suất của Jetson, khoảng 100-120 mili giây. Điều này là cao hơn đáng kể so với độ trễ của nhận thức của con người, được biết là nhanh như mili giây. Độ trễ camera cao hơn có thể ảnh hưởng tiêu cực đến hiệu suất điều khiển, đặc biệt là đối với các ứng dụng quan trọng về an toàn, bởi vì mạng lưới thần kinh sâu sẽ phân tích các cảnh cũ.

Có nhiều lĩnh vực chúng ta có thể khám phá để đẩy dự án này đi xa hơn và thu được kết quả thậm chí thuyết phục hơn. Trong tương lai, tôi tiếp tục nghiên cứu các cách để đạt được độ chính xác dự đoán tốt hơn trong việc đào tạo mạng, xác định và sử dụng camera có độ trễ thấp, cũng như tăng them khả năng nhận dạng đa dạng hơn của máy tính với bộ dữ liệu lớn hơn. Hơn nữa, tôi sẽ tiếp tục nghiên cứu, mở rộng phạm vi ứng dụng của hệ thống Machine Vision ngoài việc phân loại để hạn chế tối thiểu tác động của con người đến khu vực sản xuất, nhằm đảm bảo an toàn và tối ưu hóa sản lượng.

TÀI LIỆU THAM KHẢO Tiếng Việt

[1] Vũ Hữu Tiệp.” Machine Learning Co Ban”. Nha xuat ban Khoa Hoc va Ky Thuat.

[2] Nguyễn Thanh Tuấn (2019). “Deep Learning Cơ Bản”. Ebook

Tiếng Anh

[3] LeCun, Y., Boser, B., Denker, J. S., Henderson, D., Howard, R. E., Hubbard, W., & Jackel, L. D. (1989). “Backpropagation applied to handwritten zip code recognition. Neural computation”, 1(4), pp. 541-551.

[4] Krizhevsky, A., Sutskever, I., & Hinton, G. E. (2012). “Imagenet classification with deep convolutional neural networks. In Advances in neural information processing systems” , pp. 1097-1105.

[5] N. Otterness, M. Yang, S. Rust, E. Park, J. H. Anderson, F. D. Smith, Berg, and S. Wang (2017).” An Evaluation of the NVIDIA TX1 for Supporting Real-Time Computer-Vision Workloads. In IEEE Real-Time and Embedded Technology and Applications Symposium (RTAS)”, pages 353–364. IEEE,

[6] Srikanth Tammina (2019). “Transfer learning using VGG-16 with Deep Convolutional Neural Network for Classifying Images”. ISSN 2250-3153. [7] Aurélien Géron (2019). “Hands-on Machine Learning with Scikit-Learn, Keras,

and TensorFlow”. O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, pages 431-469.

[8] Ding, Zhengming, and Yun Fu (2016). "Robust Transfer Metric Learning for Image Classification." .IEEE Transactions on Image Processing.

PHỤ LỤC

Phụ lục 1: Chương trình huấn luyện mô hình nhận dạng

#Import packages

from keras.applications.vgg16 import VGG16 from keras.preprocessing import image

from keras.preprocessing.image import ImageDataGenerator from keras.layers import Dense, Conv2D, MaxPool2D , Flatten from keras.applications.vgg16 import preprocess_input

from keras.layers import Dense import numpy as np

import keras

from keras import models, layers, optimizers from keras.callbacks import TensorBoard import os, glob

from sklearn.model_selection import train_test_split from keras.utils import np_utils

from keras import backend as K import os

import matplotlib.pyplot as plt

from keras.callbacks import TensorBoard

vgg_conv = VGG16(weights='imagenet', include_top=False, input_shape=(224, 22 4, 3))

# Freeze the layers except the last 4 layers for layer in vgg_conv.layers[:-8]:

layer.trainable = False

# Check the trainable status of the individual layers # for layer in vgg_conv.layers:

model = models.Sequential()

# Add the vgg convolutional base model model.add(vgg_conv) # model.add(Conv2D(input_shape=(224,224,3),filters=16,kernel_size=(3,3),paddin g="same", activation="relu")) # model.add(MaxPool2D(pool_size=(2,2),strides=(2,2))) # model.add(Conv2D(filters=32,kernel_size=(3,3),padding="same", activation="rel u")) # model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))

# model.add(Conv2D(filters=64, kernel_size=(3,3), padding="same", activation="re lu"))

# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))

# model.add(Conv2D(filters=126, kernel_size=(3,3), padding="same", activation=" relu"))

# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))

# model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation=" relu"))

# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))

# model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation=" relu"))

# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2))) # Add new layers

model.add(layers.Flatten())

model.add(layers.Dense(128, activation='relu')) model.add(layers.Dense(2, activation='softmax'))

# Show a summary of the model. Check the number of trainable parameters model.summary()

train_datagen = ImageDataGenerator(rescale=1./255, horizontal_flip=True)

validation_datagen = ImageDataGenerator(rescale=1./255, horizontal_flip=True)

# Change the batchsize according to your system RAM train_batchsize = 8

val_batchsize = 8 image_size = 224

logsdir = os.path.join(os.getcwd(),"logs_0410") train_dir = "D:\\Do an\\Dataset\\data\\train\\" validation_dir = "D:\\Do an\\Dataset\\data\\test\\" train_generator = train_datagen.flow_from_directory( train_dir, target_size=(image_size, image_size), batch_size=train_batchsize, class_mode='categorical') validation_generator = validation_datagen.flow_from_directory( validation_dir, target_size=(image_size, image_size), batch_size=val_batchsize, class_mode='categorical', shuffle=False)

checkpoint_path = os.path.join(logsdir, "{epoch:04d}.h5") tensorboard = [TensorBoard(log_dir=logsdir,

histogram_freq=0, write_graph=True, write_images=False), keras.callbacks.ModelCheckpoint(checkpoint_path,

verbose=0, save_best_only=False, save_weights_only=False),] # Compile the model

optimizer=optimizers.Adam(lr=1e-5), metrics=['acc'])

# Train the model

history = model.fit_generator( train_generator, steps_per_epoch=train_generator.samples/train_generator.batch_size , epochs=20, validation_data=validation_generator, validation_steps=validation_generator.samples/validation_generator. batch_size, verbose=1, callbacks=tensorboard) acc = history.history['acc'] val_acc = history.history['val_acc'] loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(len(acc)) #Show plots

plt.plot(epochs, acc, 'b', label='Training acc') plt.plot(epochs, val_acc, 'r', label='Validation acc') plt.title('Training and validation accuracy')

plt.legend() plt.figure()

plt.plot(epochs, loss, 'b', label='Training loss') plt.plot(epochs, val_loss, 'r', label='Validation loss') plt.title('Training and validation loss')

plt.legend() plt.show()

Phụ lục 2: Chương trình chạy mô hình và xử lý ảnh phát hiện lỗi #Import Pakages import keras import cv2 import numpy as np import time import keras import os

from keras.models import load_model

from keras.preprocessing.image import ImageDataGenerator from matplotlib import pyplot as plt

import matplotlib matplotlib.use('TkAgg')

def findContours(img, numberOfContours, reverse = True): # tìm đường biên của o bj

# if dim(img) == 3:

# raise Exception "The function should be give 1 channel but got 3 channels" #cv2.CHAIN_APPROX_SIMPLE or cv2.CHAIN_APPROX_NONE

contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_AP PROX_SIMPLE)

# reverse = True : Sort follow max area. If False, sort follow min area

contours = sorted(contours, key = cv2.contourArea, reverse = reverse)[:numberO fContours]

return contours

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # chuyển thành ảnh g ray

img_sub = cv2.subtract(img[:,:,0], img_gray) # lấy kênh red - ảnh gray img_sub[:100,:] = 255

#ret, img_bw = cv2.threshold(img_sub, 0, 255, cv2.THRESH_BINARY_INV + c v2.THRESH_OTSU)

ret, img_bw = cv2.threshold(img_sub, 20, 255, cv2.THRESH_BINARY_INV) kernel = np.ones((7,7),np.uint8)

img_bw = cv2.dilate(img_bw ,kernel,iterations = 3) contours = findContours(img_bw, 1) # tìm đường bao x_min, y_min, w, h = cv2.boundingRect(contours[0]) return img_bw, x_min, y_min, w, h

def predict_img(img, model, threshold):

img_bw, x_min, y_min, w, h = segmentation(img)

img_obj = img[y_min - 10: y_min + 830, x_min - 20: x_min + 400]

idx_left = np.where(img_bw[y_min + 100: y_min+750, x_min + 20 : x_min + 21 ] == 0)

idx_right = np.where(img_bw[y_min + 100: y_min+750, x_min - 20 + w: x_min + w - 19] == 0) if len(idx_left[0]) > 150 or len(idx_right[0]) > 150: print("Defective Can") print(len(idx_left[0]), len(idx_right[0])) return False if img_obj.shape[0] != img_obj.shape[1]*2: img_obj = cv2.resize(img_obj, (420, 840)) #bot print(img_obj.shape)

img = img_obj[420: 840, :] img = cv2.resize(img, (224, 224)) img = img*1./255 img = img.reshape(-1,224,224,3) output = model.predict(img) # [[0.3, 0.7]] if output[0][1] < threshold: return False #mid img = img_obj[210: 630, :] img = cv2.resize(img, (224, 224)) img = img*1./255 img = img.reshape(-1,224,224,3) output = model.predict(img) if output[0][1] < threshold: return False #top img = img_obj[0: 420, :] img = cv2.resize(img, (224, 224)) img = img*1./255 img = img.reshape(-1,224,224,3) output = model.predict(img) if output[0][1] < threshold: return False return True model = load_model("0012.h5") img = cv2.imread("virtual.jpg")

img = img*1./255 img = img.reshape(-1,224,224,3) _ = model.predict(img) print("Loaded model") import sys sys.path.append('/opt/nvidia/jetson-gpio/lib/python/') sys.path.append('/opt/nvidia/jetson-gpio/lib/python/Jetson/GPIO') import RPi.GPIO as GPIO

import time # Pin Definitions

#output_pin = 18 # BOARD pin 12, BCM pin 18 # Pin Setup:

# Board pin-numbering scheme GPIO.setmode(GPIO.BCM)

# set pin as an output pin with optional initial state of HIGH GPIO.setup(18, GPIO.OUT, initial=GPIO.LOW)

GPIO.setup(23, GPIO.IN) # set pin as an input pin path = "/home/phamviet/Desktop/DATN/loi"

files = [i for i in os.listdir(path) if i.endswith(".jpg")] n = 0

cap_1 = cv2.VideoCapture(0) # camera 1 cap_2 = cv2.VideoCapture(1) # camera 2

try:

while(True):

_, image_1 = cap_1.read() _, image_2 = cap_2.read() image_1 = cv2.transpose(image_1,0) image_2 = cv2.transpose(image_2,0) #image_1 = cv2.flip(image_1, 0)

if GPIO.input(23) == GPIO.LOW: # tin hieu tu cam bien gui ve cv2.imshow("", cv2.resize(image_1, (240, 320)))

if cv2.waitKey(1) == 27: break

continue

print("Co object")

flag_inspection_1 = predict_img(image_1, model, 0.5) flag_inspection_2 = predict_img(image_2, model, 0.5) if flag_inspection_1 and flag_inspection_2:

print("Ok") cv2.circle(image_1, (650, 70), 50, (0,255,0), -1) else: print("Defect") GPIO.output(18, GPIO.HIGH) time.sleep(0.5) GPIO.output(18, GPIO.LOW) cv2.circle(image_1, (650, 70), 50, (0,0,255), -1) n = n + 1 cv2.imshow("", cv2.resize(image_1, (360, 640))) print("time: ", time.time()- start)

break finally:

GPIO.cleanup()

Một phần của tài liệu Nghiên cứu và ứng dụng machine vision phát hiện sản phẩm lỗi trong công nghiệp (Trang 86)

Tải bản đầy đủ (PDF)

(104 trang)