使用 PyTorch 和 OpenCV 实现简单卷积神经网络(CNN)的过程

使用 PyTorch 和 OpenCV 实现简单卷积神经网络(CNN)的过程,如何构建一个简单的卷积神经网络模型,并通过使用预定义的滤波器对灰度图像进行卷积操作和激活函数处理,最终可视化了卷积层和激活层的输出结果。

1.图像处理:

使用 OpenCV 读取图像,并将彩色图像转换为灰度图像。
进行灰度图像的归一化处理,使像素值在 0 到 1 之间。

2.卷积操作:

定义了一个包含卷积层的神经网络模型。
使用预定义的滤波器初始化卷积层的权重。

3.神经网络模型:创建了一个简单的神经网络类 Net,包含一个卷积层,该卷积层使用预定义的滤波器进行初始化,并在前向传播中应用 ReLU 激活函数。

4.可视化:
使用 Matplotlib 展示了原始灰度图像和定义的滤波器。
可视化了卷积层和激活层的输出,展示了图像在卷积操作和激活函数后的变化。

5.PyTorch 张量:
将 NumPy 数组转换为 PyTorch 张量,并将其传递到神经网络模型中进行处理。

import cv2
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import os
# 设置环境变量以避免 OpenMP 问题
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
# 指定图像文件的路径。
img_path = 'data/udacity_sdc.png'


bgr_img = cv2.imread(img_path)
# 使用 OpenCV 读取图像 ()。将图像从BGR(彩色)转换为灰度。
gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)

# 对灰度图像进行归一化,使其像素值在 [0, 1] 范围内。
gray_img = gray_img.astype("float32")/255

# 使用 Matplotlib 显示灰度图像。
plt.imshow(gray_img, cmap='gray')
plt.show()

# 定义一组将在卷积层中使用的过滤器(内核)。创建初始筛选器的变体。
filter_vals = np.array([[-1, -1, 1, 1], [-1, -1, 1, 1], [-1, -1, 1, 1], [-1, -1, 1, 1]])

print('Filter shape:', filter_vals.shape)

filter_1 = filter_vals
filter_2 = -filter_1
filter_3 = filter_1.T
filter_4 = -filter_3

filters = np.array([filter_1, filter_2, filter_3, filter_4])

print('Filter 1 \n', filter_1)
#  使用 Matplotlib 可视化定义的过滤器。对筛选器中每个元素的值进行注释。
fig = plt.figure(figsize=(10, 5))
for i in range(4):
    ax = fig.add_subplot(1, 4, i+1, xticks=[], yticks=[])
    ax.imshow(filters[i], cmap='gray')
    ax.set_title('Filter %s' % str(i+1))
    width, height = filters[i].shape
    for x in range(width):
        for y in range(height):
            ax.annotate(str(filters[i][x][y]), xy=(y, x),
                        horizontalalignment='center',
                        verticalalignment='center',
                        color='white' if filters[i][x][y] < 0 else 'black')

# 定义一个带有卷积层的简单神经网络类 ()。卷积层的权重使用定义的滤波器进行初始化。
# forward 方法计算卷积层的输出并应用 ReLU 激活函数。
class Net(nn.Module):
    def __init__(self, weight):
        super(Net, self).__init__()
        k_height, k_width = weight.shape[2:]
        self.conv = nn.Conv2d(1, 4, kernel_size=(k_height, k_width), bias=False)
        self.conv.weight = torch.nn.Parameter(weight)

    def forward(self, x):
        conv_x = self.conv(x)
        activated_x = F.relu(conv_x)
        return conv_x, activated_x

# 将过滤器的 NumPy 数组转换为 PyTorch 张量,并使用指定的权重实例化神经网络模型。
weight = torch.from_numpy(filters).unsqueeze(1).type(torch.FloatTensor)
model = Net(weight)

# 打印神经网络模型的架构。
print(model)

def viz_layer(layer, n_filters=4):
    fig = plt.figure(figsize=(20, 20))

    for i in range(n_filters):
        ax = fig.add_subplot(1, n_filters, i+1, xticks=[], yticks=[])
        ax.imshow(np.squeeze(layer[0, i].data.numpy()), cmap='gray')
        ax.set_title('Output %s' % str(i+1))

# 使用 Matplotlib 显示原始灰度图像。
plt.imshow(gray_img, cmap='gray')
plt.show()

# 可视化原始过滤器。
fig = plt.figure(figsize=(12, 6))
fig.subplots_adjust(left=0, right=1.5, bottom=0.8, top=1, hspace=0.05, wspace=0.05)
for i in range(4):
    ax = fig.add_subplot(1, 4, i+1, xticks=[], yticks=[])
    ax.imshow(filters[i], cmap='gray')
    ax.set_title('Filter %s' % str(i+1))

# 将归一化灰度图像转换为具有适当尺寸的 PyTorch 张量,以用于单通道图像。
gray_img_tensor = torch.from_numpy(gray_img).unsqueeze(0).unsqueeze(1)

# 将灰度图像传递到神经网络中,得到卷积层和激活层的输出。
conv_layer, activated_layer = model(gray_img_tensor)

# 可视化卷积层的输出。
viz_layer(conv_layer)

# 可视化激活层的输出。
viz_layer(activated_layer)

plt.show()

你可能感兴趣的:(pytorch,opencv,cnn)