import numpy as np
import matplotlib.pyplot as plt
import mindspore as ms
import mindspore.nn as nn
from mindspore import Tensor, context
from mindspore.dataset import MnistDataset
from mindspore.dataset.transforms import TypeCast
from mindspore.dataset.vision import Decode, Resize, Normalize, HWC2CHW
import mindquantum as mq
from mindquantum.core.circuit import Circuit
from mindquantum.core.gates import RY, X
from mindquantum.core.operators import QubitOperator, Hamiltonian
from mindquantum.simulator import Simulator
import os
import os
import gzip
import urllib.request
import numpy as np
# 设置运行模式
context.set_context(mode=context.PYNATIVE_MODE, device_target="CPU")
## 超参数
n_epochs = 30
n_layers = 1
n_train = 50
n_test = 30
n_channels = 4
DATA_DIR = "./MNIST_Data"
SAVE_PATH = "./results/"
os.makedirs(SAVE_PATH, exist_ok=True)
PREPROCESS = True
np.random.seed(0)
ms.set_seed(0)
def load_mnist_with_download(data_dir, num_train, num_test):
"""使用 MindSpore 的 MnistDataset 自动下载 MNIST"""
# 训练集
train_dataset = MnistDataset(
dataset_dir=data_dir,
usage='train',
num_samples=num_train,
shuffle=False,
num_parallel_workers=1,
sampler=None
)
# 测试集
test_dataset = MnistDataset(
dataset_dir=data_dir,
usage='test',
num_samples=num_test,
shuffle=False,
num_parallel_workers=1,
sampler=None
)
def preprocess(image, label):
image = image.asnumpy().astype(np.float32) / 255.0 # 归一化到 [0, 1]
image = np.expand_dims(image, -1) # 添加通道维度 (28,28) -> (28,28,1)
return image, int(label.asnumpy())
train_images, train_labels = [], []
for d in train_dataset.create_tuple_iterator(output_numpy=False):
img_tensor, lbl_tensor = d[0], d[1]
img_np, lbl_np = preprocess(img_tensor, lbl_tensor)
train_images.append(img_np)
train_labels.append(lbl_np)
test_images, test_labels = [], []
for d in test_dataset.create_tuple_iterator(output_numpy=False):
img_tensor, lbl_tensor = d[0], d[1]
img_np, lbl_np = preprocess(img_tensor, lbl_tensor)
test_images.append(img_np)
test_labels.append(lbl_np)
return (np.array(train_images), np.array(train_labels)), \
(np.array(test_images), np.array(test_labels))
print("Loading MNIST (auto-download if needed)...")
(train_images, train_labels), (test_images, test_labels) = load_mnist_with_download(DATA_DIR, n_train, n_test)
print(f"Train images shape: {train_images.shape}") # (50, 28, 28, 1)
print(f"Test images shape: {test_images.shape}") # (30, 28, 28, 1)
## 构建量子卷积器
class QuantumConvolution:
def __init__(self, n_wires=4, n_layers=1):
self.n_wires = n_wires
self.n_layers = n_layers
self.rand_params = np.random.uniform(low=0, high=2 * np.pi, size=(n_layers * n_wires,))
self.circuit = self._build_circuit()
def _build_circuit(self):
circ = Circuit()
for j in range(self.n_wires):
circ += RY(f'phi_{j}').on(j)
param_idx = 0
for _ in range(self.n_layers):
for j in range(self.n_wires):
theta = self.rand_params[param_idx]
circ += RY(theta).on(j)
param_idx += 1
for j in range(self.n_wires - 1):
circ += X.on(j + 1, j)
return circ
def measure_z_expval(self, inputs):
sim = Simulator('mqvector', self.n_wires)
total_circ = Circuit()
for j, val in enumerate(inputs):
total_circ += RY(np.pi * val).on(j)
total_circ += self.circuit.remove_noise()
sim.apply_circuit(total_circ)
results = []
for i in range(self.n_wires):
hamiltonian = Hamiltonian(QubitOperator(f'Z{i}'))
exp_val = sim.get_expectation(hamiltonian)
results.append(exp_val.real)
return np.array(results)
qconv = QuantumConvolution(n_channels, n_layers)
## 经典滤波器
def rotation_y(angle):
c = np.cos(np.pi * angle)
s = np.sin(np.pi * angle)
return np.array([[c, -s], [s, c]])
def classic_filter(image):
out = np.zeros((14, 14, n_channels))
for j in range(0, 28, 2):
for k in range(0, 28, 2):
pixels = [image[j,k,0], image[j,k+1,0], image[j+1,k,0], image[j+1,k+1,0]]
features = [np.trace(rotation_y(p)) for p in pixels]
for c in range(n_channels):
out[j//2, k//2, c] = features[c]
return out
## 量子卷积
def quanv(image):
out = np.zeros((14, 14, n_channels))
for j in range(0, 28, 2):
for k in range(0, 28, 2):
pixels = [image[j,k,0], image[j,k+1,0], image[j+1,k,0], image[j+1,k+1,0]]
q_results = qconv.measure_z_expval(pixels)
for c in range(n_channels):
out[j//2, k//2, c] = q_results[c]
return out
## 应用滤波
def apply_filter(images, filter_type):
filtered = []
desc = "Classic" if filter_type == 0 else "Quantum"
print(f"Pre-processing with {desc} filter:")
for idx, img in enumerate(images):
print(f"{idx+1}/{len(images)}", end="\r")
if filter_type == 0:
filtered.append(classic_filter(img))
else:
filtered.append(quanv(img))
return np.array(filtered)
if PREPROCESS:
filtered_train_images = apply_filter(train_images, 0)
filtered_test_images = apply_filter(test_images, 0)
q_train_images = apply_filter(train_images, 1)
q_test_images = apply_filter(test_images, 1)
np.save(SAVE_PATH + "filtered_train_images.npy", filtered_train_images)
np.save(SAVE_PATH + "filtered_test_images.npy", filtered_test_images)
np.save(SAVE_PATH + "q_train_images.npy", q_train_images)
np.save(SAVE_PATH + "q_test_images.npy", q_test_images)
# 加载保存的数据
filtered_train_images = np.load(SAVE_PATH + "filtered_train_images.npy")
filtered_test_images = np.load(SAVE_PATH + "filtered_test_images.npy")
q_train_images = np.load(SAVE_PATH + "q_train_images.npy")
q_test_images = np.load(SAVE_PATH + "q_test_images.npy")
## 可视化对比(略,同上)
n_samples = 4
fig, axes = plt.subplots(5 + n_channels, n_samples, figsize=(10, 20))
for k in range(n_samples):
axes[0][k].set_title(f"Input {k}")
axes[0][k].imshow(train_images[k,:,:,0], cmap="gray")
axes[0][k].axis("off")
for c in range(n_channels):
axes[1+c][k].imshow(filtered_train_images[k,:,:,c], cmap="gray")
axes[1+c][k].axis("off")
if k == 0: axes[1+c][k].set_ylabel(f"Ch.{c}")
for c in range(n_channels):
row = 1 + n_channels + c + 1
axes[row][k].imshow(q_train_images[k,:,:,c], cmap="gray")
axes[row][k].axis("off")
if k == 0: axes[row][k].set_ylabel(f"Q-Ch.{c}")
plt.tight_layout()
plt.show()
## 定义模型
class MyModel(nn.Cell):
def __init__(self, num_classes=10):
super().__init__()
self.flatten = nn.Flatten()
self.dense = nn.Dense(14*14*n_channels, num_classes)
self.softmax = nn.Softmax()
def construct(self, x):
x = self.flatten(x)
x = self.dense(x)
return self.softmax(x)
## 训练函数(略)
def train_model(train_x, train_y, test_x, test_y, name):
model = MyModel()
loss_fn = nn.SparseCategoricalCrossentropy(reduction='mean')
optimizer = nn.Adam(model.trainable_params(), learning_rate=0.001)
def forward_fn(data, label):
logits = model(data)
loss = loss_fn(logits, label)
return loss
grad_fn = ms.value_and_grad(forward_fn, None, optimizer.parameters)
def train_step(data, label):
loss, grads = grad_fn(data, label)
optimizer(grads)
return loss
train_ds = MnistDataset(DATA_DIR, usage='train', num_samples=n_train)
train_ds = train_ds.batch(4)
test_ds = MnistDataset(DATA_DIR, usage='test', num_samples=n_test)
test_ds = test_ds.batch(4)
history = {"loss":[], "accuracy":[], "val_loss":[], "val_accuracy":[]}
for epoch in range(n_epochs):
model.set_train(True)
total_loss, correct, total = 0.0, 0, 0
num_batches = 0
for d in train_ds.create_tuple_iterator(output_numpy=False):
img, lbl = d[0].asnumpy(), d[1].asnumpy()
img_proc = []
for i in range(len(img)):
img_proc.append(quanv(img[i])) # 示例:使用量子滤波
img_proc = np.array(img_proc)
data_tensor = Tensor(img_proc, ms.float32)
label_tensor = Tensor(lbl, ms.int32)
loss = train_step(data_tensor, label_tensor)
total_loss += float(loss.asnumpy())
num_batches += 1
pred = model(data_tensor)
pred_label = pred.argmax(axis=1)
correct += (pred_label == label_tensor).asnumpy().sum()
total += len(label_tensor)
acc = correct / total
history["loss"].append(total_loss / num_batches)
history["accuracy"].append(acc)
print(f"Epoch [{epoch+1}/{n_epochs}] Loss: {history['loss'][-1]:.4f}, Acc: {acc:.4f}")
ms.save_checkpoint(model, SAVE_PATH + f"{name}_model.ckpt")
return history
# 示例训练调用(可替换为经典/量子输入)
print("\n=== Training Quantum-Filtered Model ===")
_ = train_model(None, None, None, None, "demo_quantum")
修改上述代码,直接使用mindspore.dataset的mnist数据集
最新发布