作业1要求:加载数据,显示图像
MNIST
• Show MNIST images and ground truth
• Build dictionary or tuples
• Build an iterator
• Segment the data properly
• Read and show 3 plane medical images in dicom and nifti
作答过程:
解读:(1)MNIST(Modified National Institute of Standards and Technology database)是机器学习领域最经典的手写数字图像数据集,常被称为深度学习界的“Hello World”。它由美国国家标准与技术研究院(NIST)整理,包含60,000张训练图像和10,000张测试图像,每张图像为28×28像素的灰度图,对应0-9的手写数字标签。该数据集广泛用于算法验证和教学,是入门图像识别任务的标准化基准。

(2)NPZ文件是NumPy库用于存储多个数组的压缩文件格式。它通过键值对存储多个NumPy数组,类似字典结构,支持同时保存训练数据、标签等关联数组。文件内部采用压缩技术,相比多个NPY文件更节省空间。深度学习领域常用NPZ文件存储训练集、验证集等关联数据,通过numpy.load()加载后可直接按名称访问数组。
一、加载图像
1、检查实际键名
# 首先查看NPZ文件中包含哪些数组键名:
with np.load('/HW1-data/mnist.npz') as data:
# 显示所有可用的键名
print(data.files)
['data', 'label']
2、读取NPZ文件
# 使用with语句读取文件可以确保文件资源被正确管理,避免资源泄漏
# 使用allow_pickle=True参数可以加载序列化的数据
with np.load('/HW1-data/mnist.npz', allow_pickle=True) as data:
data1 = data['data']
label1 = data['label']
print(data1) # 输出: [1 2 3]
print(label1) # 输出: [4 5 6]
[[0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] ... [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0]] [0. 0. 0. ... 9. 9. 9.]
3、打印图像和标签形状
print("图像形状:", data1.shape)
print("标签形状:", label1.shape)
图像形状: (70000, 784) # 图像一共70000张,大小为784=28x28 标签形状: (70000,)
4、调整数据形状
MNIST数据集中的图像数据原本是28×28像素的二维数组,但在存储时被展平成了784个元素的一维向量。要正确显示图像,需要将这个一维数组重新调整为二维形状。
#批量处理:如果需要处理多个图像,可以使用向量化操作
data1_reshaped = data1.reshape(-1, 28, 28)
print(data1.shape) # 输出: (784,)
print(data1_reshaped.shape) # 输出: (28, 28)
(70000, 784) (70000, 28, 28)
注:
reshape:仅返回新形状的视图,原数据保持不变。
resize:直接修改原数组的形状。若需永久改变形状,应使用此方法。
5、展示图像(单张)
plt.figure(figsize=(6, 6))
index = 0 # 可以改为0-69999之间的任意数字
plt.imshow(data1_reshaped[index], cmap='gray')
plt.title(f"Label: {label1[index]}")
plt.show()

6、展示图像(多张)
fig, axes = plt.subplots(8, 8, figsize=(12, 12))
for i, ax in enumerate(axes.flat):
ax.imshow(data1_reshaped[i], cmap='gray')
ax.set_title(f"Label: {label1[i]}")
ax.axis('off')
plt.tight_layout()
plt.show()

二、构建字典或元组
1、构建元组
元组优势:结构简单,内存占用少,适合固定顺序的数据。
# 创建元组结构
mnist_tuple = (data1_reshaped, label1)
# 访问示例
images, labels = mnist_tuple
print(f"元组中的图像形状: {images.shape}")
print(f"元组中的标签形状: {labels.shape}")
元组中的图像形状: (70000, 28, 28) 元组中的标签形状: (70000,)
2、构建字典结构
字典优势:键名访问更直观,适合需要明确标识的场景。
(1)创建字典
# 创建字典结构
mnist_dict = {
'images': data1_reshaped, # 形状为(-1, 28, 28)
'labels': label1, # 形状为(70000,)
'metadata': {
'num_samples': data1_reshaped.shape[0],
'image_height': 28,
'image_width': 28
}
}
# 访问示例
print(f"图像数量: {mnist_dict['metadata']['num_samples']}")
print(f"单张图像形状: ({mnist_dict['metadata']['image_height']}, {mnist_dict['metadata']['image_width']})")
图像数量: 70000 单张图像形状: (28, 28)
(2)创建扩展的字典结构
# 确保标签为整数类型
label1_int = label1.astype(np.int64)
# 创建详细字典结构
detailed_mnist_dict = {
'dataset': 'MNIST',
'features': {
'image_data': data1_reshaped,
'ground_truth': label1
},
'statistics': {
'total_images': data1_reshaped.shape[0],
'unique_labels': np.unique(label1),
'label_distribution': np.bincount(label1_int)
}
}
print(f"数据集名称: {detailed_mnist_dict['dataset']}")
print(f"图像数量: {detailed_mnist_dict['statistics']['total_images']}")
print(f"单张图像形状: {data1_reshaped[0].shape}")
print(f"标签类别: {detailed_mnist_dict['statistics']['unique_labels']}")
print(f"标签分布: {detailed_mnist_dict['statistics']['label_distribution']}")
print(f"图像数据类型: {data1_reshaped.dtype}")
print(f"标签数据类型: {label1.dtype}")
数据集名称: MNIST 图像数量: 70000 单张图像形状: (28, 28) 标签类别: [0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] 标签分布: [6903 7877 6990 7141 6824 6313 6876 7293 6825 6958] 图像数据类型: uint8 标签数据类型: float64
三、构建迭代器
解读:迭代器是软件设计模式中的一种对象遍历接口,它允许开发者遍历容器(如链表、数组等)中的元素,而无需了解容器的底层内存分配细节。在编程中,迭代器作为一个数据流对象,能够依次返回序列中的每个元素,直至数据被取完且不会被重复使用。
在具体实现上,迭代器需要遵循特定的协议。例如在Python中,迭代器协议要求对象实现__iter__和__next__两个方法。__iter__方法返回迭代器对象本身,这是for循环使用迭代器的前提;而__next__方法负责返回容器中的下一个元素,当没有更多元素时则抛出StopIteration异常。
特点:
- 支持批量数据加载
- 实现标准迭代器协议
- 自动处理数据遍历结束
(1)构建迭代器:
class SimpleMNISTIterator:
def __init__(self, mnist_dict, batch_size=32):
self.images = mnist_dict['features']['image_data']
self.labels = mnist_dict['features']['ground_truth']
self.batch_size = batch_size
self.num_samples = mnist_dict['statistics']['total_images']
self.current_index = 0
def __iter__(self):
return self
def __next__(self):
if self.current_index >= self.num_samples:
self.current_index = 0
raise StopIteration
end_index = self.current_index + self.batch_size
batch_images = self.images[self.current_index:end_index]
batch_labels = self.labels[self.current_index:end_index]
self.current_index = end_index
return batch_images, batch_labels
(2)使用迭代器
# 创建并使用迭代器
iterator = SimpleMNISTIterator(detailed_mnist_dict, batch_size=16)
print("MNIST数据迭代器演示:")
for i, (imgs, lbls) in enumerate(iterator):
print(f"批次 {i+1}: 图像 {imgs.shape}, 标签 {lbls.shape}")
四、分割数据
(1)分割数据集:训练集和测试集为8:2。
def split_mnist_data(detailed_mnist_dict, test_size=0.2, random_state=42):
"""
将MNIST数据集按比例随机分割为训练集和测试集
参数:
detailed_mnist_dict: 包含图像和标签数据的字典
test_size: 测试集比例,默认为0.2(20%)
random_state: 随机种子,保证结果可复现
"""
# 从字典中获取数据
images = detailed_mnist_dict['features']['image_data']
labels = detailed_mnist_dict['features']['ground_truth']
# 将数据集按8:2比例随机分割
X_train, X_test, y_train, y_test = train_test_split(
images, labels, test_size=test_size, random_state=random_state
)
return X_train, X_test, y_train, y_test
(2)测试分割结果
np.random.seed(42)
# 分割数据集
X_train, X_test, y_train, y_test = split_mnist_data(detailed_mnist_dict)
print("MNIST数据集分割结果:")
print(f"训练集图像: {X_train.shape}")
print(f"训练集标签: {y_train.shape}")
print(f"测试集图像: {X_test.shape}")
print(f"测试集标签: {y_test.shape}")
print(f"分割比例: 训练集 {len(X_train)/70000*100:.1f}%, 测试集 {len(X_test)/70000*100:.1f}%")
MNIST数据集分割结果: 训练集图像: (56000, 28, 28) 训练集标签: (56000,) 测试集图像: (14000, 28, 28) 测试集标签: (14000,) 分割比例: 训练集 80.0%, 测试集 20.0%
五、读取医学影像数据
要求:Read and show 3 plane medical images in dicom and nifti
作业:
(1)dicom展示 2 维图片
# 读取DICOM文件
dcm_file_path = '/HW1-data/T1/00001.dcm'
dataset = pydicom.dcmread(dcm_file_path)
pixel_array = dataset.pixel_array # 三维体数据?
# 输出基本信息
print(f"Patient's Name: {dataset.PatientName}")
print(f"Modality: {dataset.Modality}")
print(f"Study Date: {dataset.StudyDate}")
# 来吧,展示~
plt.imshow(dataset.pixel_array, cmap=plt.cm.bone)
plt.show()
(2)nifti格式展示
# 加载NIfTI文件
img = nib.load('/Users/pangyu/Desktop/冬季课程/人工智能与医学图像分析/HW1-data/T1w.nii') # 替换为实际文件路径
data = img.get_fdata() # 获取三维数据(numpy数组)
print(f"数据形状: {data.shape}") # 输出维度信息(如:512, 512, 161)
数据形状: (256, 256, 192)
# 计算中间切片位置
depth, height, width = data.shape
# 计算中间切片位置
z_slice = depth // 2 # 轴状面切片
y_slice = height // 2 # 冠状面切片
x_slice = width // 2 # 矢状面切片
# 提取切片
axial = data[z_slice, :, :] # 轴状面
coronal = data[:, y_slice, :] # 冠状面
sagittal = data[:, :, x_slice] # 矢状面
# 可视化三个平面
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
# 显示轴状面
ax1.imshow(axial, cmap='gray')
ax1.set_title("Axial Plane")
ax1.axis('off')
# 显示冠状面
ax2.imshow(coronal, cmap='gray')
ax2.set_title("Coronal Plane")
ax2.axis('off')
# 显示矢状面
ax3.imshow(sagittal, cmap='gray')
ax3.set_title("Sagittal Plane")
ax3.axis('off')
plt.tight_layout()
plt.show()

完结撒花~
全部代码和结果在这儿:https://download.csdn.net/download/qq_28480795/92344905?spm=1011.2124.3001.6210
所用数据集在这儿:https://download.csdn.net/download/qq_28480795/92407692

5313

被折叠的 条评论
为什么被折叠?



