求助:快速生成20×20二值数据集训练Perceptron区分矩形与圆形
解决方案:快速生成数据集与感知器训练优化
一、批量生成20×20 0/1矩形、圆形样本集
1. 矩形样本生成逻辑
随机确定矩形的左上角坐标、宽高(确保完全落在20×20画布内),将矩形区域像素设为1,其余为0,用numpy实现批量生成:
import numpy as np def generate_rectangle(num_samples=100): samples = [] for _ in range(num_samples): # 随机参数,避免超出画布边界 x1 = np.random.randint(0, 16) y1 = np.random.randint(0, 16) w = np.random.randint(3, 20 - x1) h = np.random.randint(3, 20 - y1) img = np.zeros((20, 20), dtype=int) img[y1:y1+h, x1:x1+w] = 1 samples.append(img) return np.array(samples)
2. 圆形样本生成逻辑
随机确定圆心坐标、半径(确保圆形不超出画布),遍历像素计算到圆心的距离,小于等于半径的像素设为1:
def generate_circle(num_samples=100): samples = [] for _ in range(num_samples): # 随机参数,保证圆形在画布内 cx = np.random.randint(3, 17) cy = np.random.randint(3, 17) r = np.random.randint(2, min(cx, cy, 19 - cx, 19 - cy)) img = np.zeros((20, 20), dtype=int) for y in range(20): for x in range(20): if (x - cx)**2 + (y - cy)**2 <= r**2: img[y, x] = 1 samples.append(img) return np.array(samples)
3. 数据集整合
合并两类样本并打标签,打乱顺序后将二维矩阵展平为一维向量(适配感知器输入):
# 生成各500个样本 rects = generate_rectangle(500) circles = generate_circle(500) # 合并并打标签(矩形为1,圆形为-1) X = np.concatenate([rects, circles]) y = np.array([1]*500 + [-1]*500) # 打乱数据集 shuffle_idx = np.random.permutation(len(X)) X_shuffled = X[shuffle_idx] y_shuffled = y[shuffle_idx] # 展平为400维向量 X_flat = X_shuffled.reshape(len(X_shuffled), -1)
二、初代感知器训练优化
1. 感知器核心实现
基于原始算法,加入批量更新和准确率达标终止机制:
class Perceptron: def __init__(self, input_dim=400, lr=0.01): self.weights = np.random.randn(input_dim) self.bias = np.random.randn() self.lr = lr def predict(self, x): return 1 if np.dot(x, self.weights) + self.bias > 0 else -1 def train(self, X, y, epochs=100, acc_threshold=0.99): for epoch in range(epochs): errors = 0 for x, target in zip(X, y): pred = self.predict(x) if pred != target: self.weights += self.lr * (target - pred) * x self.bias += self.lr * (target - pred) errors += 1 acc = 1 - errors / len(X) if acc >= acc_threshold: print(f"训练提前终止,epoch {epoch+1},准确率 {acc:.4f}") break if (epoch+1) % 10 == 0: print(f"epoch {epoch+1},准确率 {acc:.4f}")
2. 训练与验证
# 初始化感知器 perceptron = Perceptron(lr=0.001) # 划分训练集与验证集(8:2) split_idx = int(len(X_flat)*0.8) X_train, X_val = X_flat[:split_idx], X_flat[split_idx:] y_train, y_val = y_shuffled[:split_idx], y_shuffled[split_idx:] # 开始训练 perceptron.train(X_train, y_train) # 验证集评估 val_preds = [perceptron.predict(x) for x in X_val] val_acc = sum(1 for p, t in zip(val_preds, y_val) if p == t) / len(y_val) print(f"验证集准确率:{val_acc:.4f}")
3. 关键注意事项
- 若原始像素训练效果差,说明样本可能线性不可分,可提取简单特征替代:比如矩形的宽高比、圆形的像素对称性、边缘像素数量等,将特征维度从400降至个位数,确保问题线性可分。
- 调整样本生成的参数范围(如最小尺寸、位置限制),放大两类样本的特征差异,提升感知器分类效果。
内容的提问来源于stack exchange,提问作者kot ucheniy
相关产品推荐
相关产品推荐

