PyBrain入门实践:探索机器学习基本概念

学习目标

通过本课程,学员将了解机器学习的基本概念,包括监督学习、无监督学习和强化学习,并学习如何使用PyBrain库来实现这些概念。本课程旨在通过实践操作加深学员对这些概念的理解。

相关知识点

  • 用PyBrain探索机器学习基本概念

学习内容

1 用PyBrain探索机器学习基本概念

1.1 安装依赖并导入必要的库

首先,这里需要获取PyBrain的源码库,获取方式如下:

注意:pip安装的PyBrain版本最新为0.3.0,与本课程不适配,需要编译0.3.3版本的包。PyBrain自2015年发布0.3.3版本以来就没再进行过版本更新,其源码中很多scipy引用的功能模块在当前已经全部移动到了numpy中,因此这里提供下载的PyBrain源码已经过改造,将所有原本涉及到的scipy引用替换为了numpy,直接编译即可。

下列命令行在Jupyter notebook中使用,在python命令行中需要将前面的!或%去除。

!wget https://model-community-picture.obs.cn-north-4.myhuaweicloud.com/ascend-zone/notebook_codes/b3aee5302bf611f0b414fa163edcddae/pybrain.zip --no-check-certificate
!unzip pybrain.zip

进入到源码包路径开始编译安装:

cd pybrain/
import sys
%pip install wheel==0.44.0
%pip install ./
cd ../
from pybrain.tools.shortcuts import buildNetwork
from pybrain.datasets import SupervisedDataSet, UnsupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer

from pybrain.structure import LinearLayer, SigmoidLayer, FullConnection, BiasUnit, FeedForwardNetwork
from pybrain.unsupervised.trainers.rbm import RbmGaussTrainer
from pybrain.structure.networks.rbm import Rbm

from pybrain.rl.environments.mazes import Maze, MDPMazeTask
from pybrain.rl.learners.valuebased import ActionValueTable
from pybrain.rl.learners import SARSA
from pybrain.rl.agents import LearningAgent
from pybrain.rl.experiments import Experiment
from pybrain.rl.environments import Task

import matplotlib.pyplot as pylab
import numpy as np
1.2 监督学习

监督学习是机器学习中最常见的类型之一,它涉及使用标记的数据集来训练模型,以便模型能够预测或分类新的、未见过的数据。在监督学习中,每个训练样本都包含输入数据和对应的正确答案(标签)。通过这种方式,模型可以学习输入数据与输出标签之间的关系,从而在遇到新数据时做出准确的预测。

1.2.1 理论知识

监督学习可以进一步分为回归和分类两种任务。回归任务的目标是预测一个连续值,例如房价预测;而分类任务的目标是将数据分配到预定义的类别中,例如垃圾邮件检测。监督学习的关键在于选择合适的模型和损失函数,以及通过优化算法调整模型参数,以最小化预测值与实际值之间的差异。

在PyBrain中,实现监督学习通常涉及以下几个步骤:

  1. 数据准备:收集和预处理数据,确保数据格式适合模型训练。
  2. 模型选择:选择合适的神经网络结构,例如前馈神经网络(Feedforward Neural Network)。
  3. 训练模型:使用训练数据集训练模型,调整模型参数以最小化损失函数。
  4. 评估模型:使用测试数据集评估模型的性能,确保模型具有良好的泛化能力。
1.2.2 实践操作

下面是一个简单的例子,使用PyBrain实现一个监督学习任务,预测房价。

# 数据准备
# 假设有一个简单的数据集,包含房屋面积(平方米)和价格(万元)
data = np.array([
    [50, 100],
    [60, 120],
    [70, 140],
    [80, 160],
    [90, 180]
])

# 创建监督数据集
ds = SupervisedDataSet(1, 1)
for x, y in data:
    ds.addSample(x, y)

# 构建神经网络
net = buildNetwork(1, 3, 1)

# 创建训练器
trainer = BackpropTrainer(net, ds)

# 训练模型
trainer.trainEpochs(1000)

# 预测新数据
new_data = np.array([100])
prediction = net.activate(new_data)
print(f"预测价格: {prediction[0]:.2f} 万元")
1.3 无监督学习

无监督学习是一种机器学习方法,它不依赖于标记的数据集,相反,无监督学习的目标是发现数据中的模式或结构,例如聚类和降维。在无监督学习中,模型通过分析数据的内在特性来学习数据的分布,从而能够对新数据进行分类或降维。

1.3.1 理论知识

无监督学习的主要任务包括聚类和降维。聚类的目标是将数据点分组到不同的类别中,使得同一类别内的数据点相似度高,而不同类别之间的数据点相似度低。常见的聚类算法有K-means、层次聚类等。降维的目标是将高维数据转换为低维数据,同时保留数据的主要特征。常见的降维算法有主成分分析(PCA)和t-SNE。

在PyBrain中,实现无监督学习通常涉及以下几个步骤:

  1. 数据准备:收集和预处理数据,确保数据格式适合模型训练。
  2. 模型选择:选择合适的无监督学习算法,例如K-means聚类。
  3. 训练模型:使用数据集训练模型,调整模型参数以发现数据中的模式。
  4. 评估模型:评估模型的性能,确保模型能够有效地发现数据中的模式。
1.3.2 实践操作

下面是一个简单的例子,使用PyBrain实现一个基于受限玻尔兹曼机(Restricted Boltzmann Machine, RBM)的无监督特征学习任务,对二维数据点进行特征提取和模式识别。

# 数据准备 - 使用具有区分度的数据集,增加样本多样性
data = np.array([
    [1, 1],     # 类别1: 低数值对
    [1.5, 1.2],
    [0.8, 1.5],
    [8, 8],     # 类别2: 高数值对
    [7.5, 8.2],
    [8.5, 7.8],
    [1, 9],     # 类别3: 高低组合
    [0.5, 8.5],
    [1.2, 9.5],
    [9, 1],     # 类别4: 低高组合
    [8.5, 0.8],
    [9.2, 1.5],
    [5, 5],     # 类别5: 中间值
    [4.5, 5.2],
    [5.5, 4.8]
])

# 数据标准化 - 重要步骤,帮助RBM训练
data_mean = np.mean(data, axis=0)
data_std = np.std(data, axis=0) + 1e-10  # 避免除零
normalized_data = (data - data_mean) / data_std

# 创建无监督数据集
ds = UnsupervisedDataSet(2)
for sample in normalized_data:
    ds.addSample(sample)

# 构建RBM网络 - 增加隐藏单元以提高表达能力
def build_rbm_network(visible_dim, hidden_dim):
    """构建RBM网络"""
    net = FeedForwardNetwork()

    bias = BiasUnit('bias')
    visible = LinearLayer(visible_dim, 'visible')
    hidden = SigmoidLayer(hidden_dim, 'hidden')  # 使用Sigmoid激活函数

    con = FullConnection(visible, hidden)
    bias_con = FullConnection(bias, hidden)

    net.addInputModule(visible)
    net.addModule(bias)
    net.addOutputModule(hidden)
    net.addConnection(con)
    net.addConnection(bias_con)

    net.sortModules()
    return Rbm(net)

# 创建RBM网络实例
net = build_rbm_network(2, 8)  # 8个隐藏单元

# 改进的训练器配置
class RbmGibbsTrainerConfig:
    def __init__(self):
        self.batchSize = len(normalized_data)  # 使用全部数据作为一个批次
        self.rWeights = 0.01                   # 学习率
        self.rHidBias = 0.01
        self.rVisBias = 0.01
        self.weightCost = 0.0005               # 权重惩罚,防止过拟
        self.iniMm = 0.4                       # 初始动量
        self.finMm = 0.95                      # 最终动量
        self.mmSwitchIter = 20                 # 动量切换迭代数
        self.maxIter = 50                      # 每次训练的迭代数
        self.visibleDistribution = 'gaussian'  # 使用高斯分布处理连续值输入

# 创建RBM训练器
cfg = RbmGibbsTrainerConfig()
trainer = RbmGaussTrainer(net, ds, cfg)

# 训练模型
print("开始训练...")
for i in range(1000):  # 训练周期
    if i % 100 == 0:
        print(f"训练周期 {i}")
    trainer.train()

# 预测新数据
test_data = np.array([
    [1, 1],       # 类别1
    [8, 8],       # 类别2
    [1, 9],       # 类别3
    [9, 1],       # 类别4
    [5, 5],       # 类别5
    [0, 0],       # 超出训练范围
    [10, 10],     # 超出训练范围
    [1, 10],      # 超出训练范围
    [10, 1]       # 超出训练范围
])

# 标准化测试数据
normalized_test_data = (test_data - data_mean) / data_std

# 获取预测结果
predictions = [net.activate(x) for x in normalized_test_data]

# 打印预测结果
print("\n预测结果:")
for i, (sample, pred) in enumerate(zip(test_data, predictions)):
    print(f"样本 {sample}: {pred.round(3)}")
1.4 强化学习

强化学习是一种通过与环境交互来学习最优行为策略的机器学习方法。在强化学习中,智能体(Agent)通过执行动作(Action)与环境(Environment)交互,环境会根据智能体的动作给出奖励(Reward)。智能体的目标是通过最大化累积奖励来学习最优策略。

1.4.1 理论知识

强化学习的核心概念包括智能体、环境、状态、动作和奖励。智能体在每个时间步选择一个动作,环境根据动作返回一个新的状态和奖励。通过不断试错,智能体逐渐学习到在不同状态下选择最优动作的策略。常见的强化学习算法有Q-learning、SARSA等。

在PyBrain中,实现强化学习通常涉及以下几个步骤:

  1. 环境定义:定义环境和状态空间,确保环境能够根据智能体的动作返回新的状态和奖励。
  2. 智能体定义:定义智能体和动作空间,确保智能体能够根据当前状态选择动作。
  3. 学习算法选择:选择合适的强化学习算法,例如Q-learning。
  4. 训练模型:通过与环境的交互,训练智能体学习最优策略。
  5. 评估模型:评估智能体的性能,确保智能体能够有效地执行任务。
1.4.2 实践操作

下面是一个简单的例子,使用PyBrain实现一个强化学习任务,训练智能体在迷宫的一个随机起点中找到出口(7, 7)。

# 创建迷宫数组
mazearray = np.array(
   [[1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 0, 0, 1, 0, 0, 0, 0, 1],
   [1, 0, 0, 1, 0, 0, 1, 0, 1],
   [1, 0, 0, 1, 0, 0, 1, 0, 1],
   [1, 0, 0, 1, 0, 1, 1, 0, 1],
   [1, 0, 0, 0, 0, 0, 1, 0, 1],
   [1, 1, 1, 1, 1, 1, 1, 0, 1],
   [1, 0, 0, 0, 0, 0, 0, 0, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1]]
)
env = Maze(mazearray, (7, 7))

# 创建任务
task = MDPMazeTask(env)
# 创建动作值表作为控制器
controller = ActionValueTable(81, 4)
controller.initialize(1.)
# 使用SARSA学习器
learner = SARSA()
# 创建智能体
agent = LearningAgent(controller, learner)
# 创建实验
experiment = Experiment(task, agent)

# 训练智能体
for i in range(1000):
    experiment.doInteractions(100)
    agent.learn()
    agent.reset()

# 可视化智能体在迷宫环境中学习到的状态值函数
pylab.gray()
pylab.ion()
state_values = controller.params.reshape(81, 4).max(1).reshape(9, 9)
pylab.pcolor(state_values)
pylab.colorbar()
pylab.show()

# 评估智能体 - 随机起始点
for i in range(10):
    print(f"\n评估轮次 {i+1}:")
    # 重置环境和智能体
    env.reset()
    agent.reset()
    # 获取初始状态并告知智能体
    state = task.getObservation()
    agent.integrateObservation(state)
    # 获取目标位置的坐标
    goal_x, goal_y = env.goal  # 直接获取坐标元组
    # 手动收集交互历史
    episode = []
    
    for step in range(100):
        action = agent.getAction()  # 获取动作
        # 执行动作并获取下一个状态
        task.performAction(action)
        next_state = task.getObservation()
        reward = task.getReward()
        # 记录状态-动作对
        episode.append((state, action, reward, next_state))
        # 更新智能体的观察
        agent.integrateObservation(next_state)
        # 转换状态ID为坐标
        state_id = int(state)  # 确保状态是整数
        x, y = state_id // env.mazeTable.shape[1], state_id % env.mazeTable.shape[1]
        # 检查是否到达目标位置
        if (x, y) == (goal_x, goal_y):
            print(f"在步骤 {step+1} 到达目标位置 ({goal_x}, {goal_y})")
            break
        # 更新状态
        state = next_state
    
    # 打印路径
    path = [step[0] for step in episode]
    print(f"路径长度: {len(path)}")
    # 打印路径的坐标表示
    path_coordinates = [(s // 9, s % 9) for s in path]
    new_path_coordinates = [(int(x[0]), int(y[0])) for x, y in path_coordinates]  # 转换为 (x, y) 形式
    print(f"路径坐标: {new_path_coordinates[:20]}")

通过本课程的学习,学员将对监督学习、无监督学习和强化学习有更深入的理解,并能够使用PyBrain库实现这些概念。希望学员在实践中不断探索,并提升机器学习技能!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐