人工智能A*算法与CNN结合- CNN 增加卷积层的数量,并对卷积核大小进行调整

以下是一个增强版的将 A* 算法与卷积神经网络(CNN)结合的代码实现,其中 CNN 增加了卷积层的数量,并对卷积核大小进行了调整。整体思路依然是先利用 A* 算法生成训练数据,再用这些数据训练 CNN 模型,最后使用训练好的模型进行路径规划。

python 复制代码
import numpy as np
import heapq
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader

# A* 算法实现
class Node:
    def __init__(self, x, y, g=float('inf'), h=float('inf'), parent=None):
        self.x = x
        self.y = y
        self.g = g
        self.h = h
        self.f = g + h
        self.parent = parent

    def __lt__(self, other):
        return self.f < other.f

def heuristic(current, goal):
    return abs(current[0] - goal[0]) + abs(current[1] - goal[1])

def astar(grid, start, goal):
    rows, cols = grid.shape
    open_list = []
    closed_set = set()

    start_node = Node(start[0], start[1], g=0, h=heuristic(start, goal))
    heapq.heappush(open_list, start_node)

    while open_list:
        current_node = heapq.heappop(open_list)

        if (current_node.x, current_node.y) == goal:
            path = []
            while current_node:
                path.append((current_node.x, current_node.y))
                current_node = current_node.parent
            return path[::-1]

        closed_set.add((current_node.x, current_node.y))

        neighbors = [(0, 1), (0, -1), (1, 0), (-1, 0)]
        for dx, dy in neighbors:
            new_x, new_y = current_node.x + dx, current_node.y + dy

            if 0 <= new_x < rows and 0 <= new_y < cols and grid[new_x][new_y] == 0 and (new_x, new_y) not in closed_set:
                new_g = current_node.g + 1
                new_h = heuristic((new_x, new_y), goal)
                new_node = Node(new_x, new_y, g=new_g, h=new_h, parent=current_node)

                found = False
                for i, node in enumerate(open_list):
                    if node.x == new_x and node.y == new_y:
                        if new_g < node.g:
                            open_list[i] = new_node
                            heapq.heapify(open_list)
                        found = True
                        break

                if not found:
                    heapq.heappush(open_list, new_node)

    return None

# 生成训练数据
def generate_training_data(grid, num_samples):
    rows, cols = grid.shape
    inputs = []
    outputs = []
    for _ in range(num_samples):
        start = (np.random.randint(0, rows), np.random.randint(0, cols))
        goal = (np.random.randint(0, rows), np.random.randint(0, cols))
        path = astar(grid, start, goal)
        if path:
            input_data = np.zeros((1, rows, cols))
            input_data[0, start[0], start[1]] = 1
            input_data[0, goal[0], goal[1]] = 2
            output_data = np.zeros((1, rows, cols))
            for point in path:
                output_data[0, point[0], point[1]] = 1
            inputs.append(input_data)
            outputs.append(output_data)
    return np.array(inputs), np.array(outputs)

# 自定义数据集类
class PathDataset(Dataset):
    def __init__(self, inputs, outputs):
        self.inputs = torch.tensor(inputs, dtype=torch.float32)
        self.outputs = torch.tensor(outputs, dtype=torch.float32)

    def __len__(self):
        return len(self.inputs)

    def __getitem__(self, idx):
        return self.inputs[idx], self.outputs[idx]

# 定义增强版卷积神经网络模型
class EnhancedPathCNN(nn.Module):
    def __init__(self):
        super(EnhancedPathCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=5, padding=2)
        self.relu1 = nn.ReLU()
        self.conv2 = nn.Conv2d(32, 64, kernel_size=5, padding=2)
        self.relu2 = nn.ReLU()
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
        self.relu3 = nn.ReLU()
        self.conv4 = nn.Conv2d(128, 64, kernel_size=3, padding=1)
        self.relu4 = nn.ReLU()
        self.conv5 = nn.Conv2d(64, 1, kernel_size=3, padding=1)

    def forward(self, x):
        x = self.relu1(self.conv1(x))
        x = self.relu2(self.conv2(x))
        x = self.relu3(self.conv3(x))
        x = self.relu4(self.conv4(x))
        x = self.conv5(x)
        return x

# 训练神经网络
def train_model(model, dataloader, criterion, optimizer, epochs):
    for epoch in range(epochs):
        running_loss = 0.0
        for inputs, labels in dataloader:
            optimizer.zero_grad()
            outputs = model(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            running_loss += loss.item()
        print(f'Epoch {epoch + 1}, Loss: {running_loss / len(dataloader)}')

# 主程序
if __name__ == "__main__":
    # 示例地图
    map_grid = np.array([
        [0, 0, 0, 0, 0],
        [0, 1, 1, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 1, 1, 0],
        [0, 0, 0, 0, 0]
    ])

    # 生成训练数据
    num_samples = 1000
    inputs, outputs = generate_training_data(map_grid, num_samples)

    # 创建数据集和数据加载器
    dataset = PathDataset(inputs, outputs)
    dataloader = DataLoader(dataset, batch_size=32, shuffle=True)

    # 初始化增强版 CNN 模型
    model = EnhancedPathCNN()

    # 定义损失函数和优化器
    criterion = nn.MSELoss()
    optimizer = optim.Adam(model.parameters(), lr=0.001)

    # 训练模型
    epochs = 10
    train_model(model, dataloader, criterion, optimizer, epochs)

    # 使用训练好的模型进行路径规划
    start = (0, 0)
    goal = (4, 4)
    input_data = np.zeros((1, 1, map_grid.shape[0], map_grid.shape[1]))
    input_data[0, 0, start[0], start[1]] = 1
    input_data[0, 0, goal[0], goal[1]] = 2
    input_tensor = torch.tensor(input_data, dtype=torch.float32)
    output = model(input_tensor)
    output_path = output.detach().numpy()[0, 0]
    path_points = np.argwhere(output_path > 0.5)
    print("增强版 CNN 预测的路径点:", path_points)

代码解释

1. A* 算法部分

这部分和之前的实现基本一致,Node 类用于表示地图中的节点,heuristic 函数计算启发式代价,astar 函数通过维护开放列表和关闭列表来搜索从起点到终点的最短路径。

2. 数据生成部分

generate_training_data 函数随机生成起点和终点,调用 A* 算法计算路径,将起点、终点信息作为输入,路径信息作为输出,生成训练数据。

3. 数据集和数据加载器部分

PathDataset 类继承自 torch.utils.data.Dataset,用于封装训练数据,DataLoader 用于批量加载数据并支持随机打乱。

4. 增强版卷积神经网络部分
  • EnhancedPathCNN 类定义了一个更复杂的 CNN 模型,增加了卷积层的数量,同时调整了卷积核的大小。具体来说,前两层使用 5x5 的卷积核,后三层使用 3x3 的卷积核,每层卷积后都接一个 ReLU 激活函数,最后一层卷积输出单通道的预测路径。
  • train_model 函数使用均方误差损失函数(nn.MSELoss)和 Adam 优化器对模型进行训练,在多个 epoch 中不断更新模型参数。
5. 主程序部分

定义示例地图,生成训练数据,创建数据集和数据加载器,初始化增强版 CNN 模型,定义损失函数和优化器,训练模型,最后使用训练好的模型进行路径规划并输出预测的路径点。

注意事项

  • 增加卷积层和调整卷积核大小可能会增加模型的复杂度和训练时间,需要确保有足够的计算资源和训练数据。
  • 可以根据实际情况进一步调整模型结构、卷积核大小、学习率等超参数,以获得更好的性能。
  • CNN 模型预测的路径不一定是最优路径,A* 算法能保证最优路径,但 CNN 可以在效率上有一定提升。
相关推荐
恒哥的爸爸6 分钟前
GPT原理笔记
人工智能·笔记·gpt
咚咚王者9 分钟前
人工智能之知识蒸馏 第五章 蒸馏优化技术:精度损失补偿方法
人工智能
kishu_iOS&AI19 分钟前
Pytorch —— 自动微分模块
人工智能·pytorch·python·深度学习·算法·线性回归
星浩AI20 分钟前
手把手带你在 Windows 安装 Hermess Agent,并接入飞书 [喂饭级教程含踩坑经验]
人工智能·后端·agent
争渡假渡21 分钟前
Claude Code 工作流 vs 人类程序员工作流
人工智能
配奇31 分钟前
集成学习(Ensemble Learning)
人工智能·机器学习·集成学习
北风toto32 分钟前
深入解析JWT Token生成原理与安全加密技术详解
算法·安全·哈希算法
新缸中之脑35 分钟前
RAG 只是权宜之计
人工智能
DeepModel36 分钟前
通俗易懂讲透 EM 算法(期望最大化)
人工智能·python·算法·机器学习
海海不掉头发37 分钟前
【AI大模型实战项目】大模型入门实战:两个落地项目保姆级教程12月14日-【项目】基于知识库RAG的物流行业信息问答系统
人工智能·python·深度学习·语言模型·自然语言处理·pycharm·scikit-learn