AD疾病分类代码报错:UnboundLocalError变量pred未赋值即引用
阿尔茨海默病图像分类任务UnboundLocalError问题解决
问题描述
在进行阿尔茨海默病(AD)图像分类任务时,计算测试集中随机图像的分类概率时触发UnboundLocalError,错误提示为局部变量'pred'在赋值前被引用。
报错栈
UnboundLocalError Traceback (most recent call last) Cell In[18], line 38 35 ax2.set_title('Alzheimer Probabilities', color="yellow", fontweight="bold", fontsize=16) 37 rand_img_no = np.random.randint(1, 32) ---> 38 random_mri_prob_bringer(image_number=rand_img_no) Cell In[18], line 7, in random_mri_prob_bringer(image_number) 4 image = images[image_number] 5 pred = model.predict(tf.expand_dims(image, 0))[0] ----> 7 probs = list(tf.nn.softmax(pred).numpy()) 8 probs_dict = dict(zip(class_dist.keys(), probs)) 10 keys = list(probs_dict.keys()) UnboundLocalError: local variable 'pred' referenced before assignment
问题原因
- 变量初始化缺失:
pred和image仅在for循环内部定义,若test_data.skip(5).take(1)未返回任何数据(比如测试集数据量不足),循环不会执行,这两个变量从未被赋值,后续引用时直接报错。 - 循环冗余隐患:
take(1)仅返回一个批次数据,用for循环遍历属于冗余写法,且放大了变量未初始化的风险。
解决方案
方案1:提前初始化变量+有效性校验
在循环前初始化变量,并增加校验确保数据正常获取:
def random_mri_prob_bringer(image_number=0): # 初始化变量,避免循环未执行时报错 image = None pred = None for images, _ in test_data.skip(5).take(1): image = images[image_number] pred = model.predict(tf.expand_dims(image, 0))[0] # 校验变量是否正常赋值 if pred is None or image is None: raise ValueError("无法从测试集获取数据,请检查test_data的有效性或skip的步数") probs = list(tf.nn.softmax(pred).numpy()) probs_dict = dict(zip(class_dist.keys(), probs)) keys = list(probs_dict.keys()) values = list(probs_dict.values()) fig, (ax1, ax2) = plt.subplots(1, 2, facecolor='black') plt.subplots_adjust(wspace=0.4) ax1.imshow(image) ax1.set_title('Brain MRI', color="yellow", fontweight="bold", fontsize=16) edges = ['left', 'bottom', 'right', 'top'] edge_color = "greenyellow" edge_width = 3 for edge in edges: ax1.spines[edge].set_linewidth(edge_width) ax1.spines[edge].set_edgecolor(edge_color) plt.gca().axes.yaxis.set_ticklabels([]) plt.gca().axes.xaxis.set_ticklabels([]) wedges, labels, autopct = ax2.pie(values, labels=keys, autopct='%1.1f%%', shadow=True, startangle=90, colors=colors, textprops={'fontsize': 8, "fontweight":"bold", "color":"white"}, wedgeprops={'edgecolor':'black'} , labeldistance=1.15) for autotext in autopct: autotext.set_color('black') ax2.set_title('Alzheimer Probabilities', color="yellow", fontweight="bold", fontsize=16) rand_img_no = np.random.randint(1, 32) random_mri_prob_bringer(image_number=rand_img_no)
方案2:直接获取批次数据(更简洁)
利用take(1)仅返回一个批次的特性,直接转换为列表获取数据,避免循环:
def random_mri_prob_bringer(image_number=0): # 直接获取批次数据,避免循环冗余 batch_list = list(test_data.skip(5).take(1)) if not batch_list: raise ValueError("无法从测试集获取数据,请检查test_data的有效性或skip的步数") images, _ = batch_list[0] # 动态生成有效索引,避免越界 if image_number >= len(images): image_number = np.random.randint(0, len(images)) image = images[image_number] pred = model.predict(tf.expand_dims(image, 0))[0] probs = list(tf.nn.softmax(pred).numpy()) probs_dict = dict(zip(class_dist.keys(), probs)) keys = list(probs_dict.keys()) values = list(probs_dict.values()) fig, (ax1, ax2) = plt.subplots(1, 2, facecolor='black') plt.subplots_adjust(wspace=0.4) ax1.imshow(image) ax1.set_title('Brain MRI', color="yellow", fontweight="bold", fontsize=16) edges = ['left', 'bottom', 'right', 'top'] edge_color = "greenyellow" edge_width = 3 for edge in edges: ax1.spines[edge].set_linewidth(edge_width) ax1.spines[edge].set_edgecolor(edge_color) plt.gca().axes.yaxis.set_ticklabels([]) plt.gca().axes.xaxis.set_ticklabels([]) wedges, labels, autopct = ax2.pie(values, labels=keys, autopct='%1.1f%%', shadow=True, startangle=90, colors=colors, textprops={'fontsize': 8, "fontweight":"bold", "color":"white"}, wedgeprops={'edgecolor':'black'} , labeldistance=1.15) for autotext in autopct: autotext.set_color('black') ax2.set_title('Alzheimer Probabilities', color="yellow", fontweight="bold", fontsize=16) rand_img_no = np.random.randint(1, 32) random_mri_prob_bringer(image_number=rand_img_no)
额外检查建议
- 确认
test_data总数据量是否足够支撑skip(5)操作,若测试集批次数量少于5,skip(5)会返回空数据集。 - 优化随机索引生成:改为
np.random.randint(0, len(images)),避免因批次大小不足32导致的索引越界错误。
内容的提问来源于stack exchange,提问作者Since 1995
相关产品推荐
相关产品推荐

