情感分类实战-experimental_run_tf_function=False 报错

本文介绍了一个使用TensorFlow 2.x搭建的IMDb影评情感分析模型,在使用带有dropout参数的SimpleRNNCell时遇到的问题及解决方案。通过在fit方法中设置experimental_run_tf_function=False,成功解决了TypeError异常,但解释了这一设置的具体作用。
部署运行你感兴趣的模型镜像

当init方法有dropout时,函数fit时报以下错误,加上experimental_run_tf_function=False,错误消失,但是不明白这句话的作用:

        self.rnn_cell0 = layers.SimpleRNNCell(units, dropout=0.2)

TypeError: An op outside of the function building code is being passed
a “Graph” tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
@tf.function
def has_init_scope():
my_constant = tf.constant(1.)
with tf.init_scope():
added = my_constant * 2
The graph tensor has name: my_rnn/simple_rnn_cell/cond/Identity:0

tensorflow.python.eager.core._SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor ‘my_rnn/simple_rnn_cell/cond/Identity:0’ shape=(None, 100) dtype=float32>]

以下为代码:

from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics, preprocessing
import tensorflow as tf
from tensorflow import keras
import numpy as np
import os
from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSession

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

config = ConfigProto(allow_soft_placement=True)
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)
assert tf.__version__.startswith("2.")

# the most frequent word
batchsz = 128
total_words = 10000
max_review_len = 80
embedding_len = 100
(x_train, y_train), (x_test, y_test) = datasets.imdb.load_data(num_words=total_words)
# x_train: (b, 80)
x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=max_review_len)
x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=max_review_len)

db_train = tf.data.Dataset.from_tensor_slices((x_train, y_train))
db_train = db_train.shuffle(1000).batch(batchsz, drop_remainder=True)
db_test = tf.data.Dataset.from_tensor_slices((x_test, y_test))
db_test = db_test.shuffle(1000).batch(batchsz, drop_remainder=True)
print(x_train.dtype, x_test.shape, tf.reduce_max(x_train), tf.reduce_max(y_train))



class MyRNN(keras.Model):
    def __init__(self, units):
        super(MyRNN, self).__init__()
        # transform text to enbedding representation
        # [B, 80]->[B,80,100]
        self.state0 = [tf.zeros([batchsz, units])]
        self.embedding = layers.Embedding(total_words, embedding_len, input_length=max_review_len)
        # [b,80,100], h_dim:64
        # RNN: cell, cell2, cell3
        # simpleRNN
        self.rnn_cell0 = layers.SimpleRNNCell(units,)
        # self.rnn_cell1 = layers.SimpleRNN()
        # fc,[b,80,100]=>[b, 64]=>[b,1]
        self.rnn_fc = layers.Dense(1)

    def call(self, inputs, training=None):
        x = inputs
        # embedding [b,80]=>[b,80,q00]
        x = self.embedding(x)
        state0 = self.state0
        for word in tf.unstack(x, axis=1):  # word:[b,100]
            # h = tf.zeros(unit,)
            out, state1 = self.rnn_cell0(word, state0, training)
            state0 = state1
        x = self.rnn_fc(out)
        prob = tf.sigmoid(x)

        return prob


def main():
    units = 64
    epochs = 4

    model = MyRNN(units)
    # model.build(input_shape=(4,80))
    # model.summary()
    model.compile(optimizer = keras.optimizers.Adam(0.001),
                  loss = tf.losses.BinaryCrossentropy(),
                  metrics=['accuracy'])
    model.fit(db_train, epochs=epochs, validation_data=db_test)

    model.evaluate(db_test)

if __name__ == '__main__':
    main()

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.15

TensorFlow-v2.15

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

import tensorflow as tf import os import matplotlib.pyplot as plt from time import time # 定义标签字典(根据实际类别修改) label_dict = { 'electrodrill': 0, 'headphones': 1, 'keyboard': 2, 'mobile_phone': 3, 'monitor': 4, 'mouse': 5, 'multimeter': 6, 'number': 7, 'oscillograph': 8, 'pliers': 9, 'printer': 10, 'screwdriver': 11, 'soldering_iron': 12, 'speaker': 13, 'tape_measure': 14, 'wrench': 15 } def data_load(data_dir, test_data_dir, img_height, img_width, batch_size): def process_image(image_path): image = tf.io.read_file(image_path) image = tf.image.decode_jpeg(image, channels=3) image = tf.image.resize(image, [img_height, img_width]) image = (image / 127.5) - 1.0 # MobileNet标准化 return image def parse_path(path): # 转换为numpy字符串处理路径 path_str = path.numpy().decode('utf-8') # 获取类别文件夹名 class_name = tf.strings.split(path_str, os.path.sep)[-2].numpy().decode('utf-8') # 从预定义的字典获取标签索引 label_idx = label_dict.get(class_name, -1) # -1表示未知类别 if label_idx == -1: raise ValueError(f"未知类别: {class_name}") return process_image(path), label_idx def map_fn(path): # 使用py_function包装Python逻辑 image, label = tf.py_function( func=parse_path, inp=[path], Tout=[tf.float32, tf.int32] ) # 设置明确的Tensor形状 image.set_shape([img_height, img_width, 3]) label.set_shape([]) # 将标签转换为one-hot编码 label = tf.one_hot(label, depth=len(label_dict)) return image, label def load_dataset(directory): # 获取所有图片路径 dataset = tf.data.Dataset.list_files(directory + '/*/*.jpg', shuffle=True) # 应用处理函数 dataset = dataset.map( map_fn, num_parallel_calls=tf.data.experimental.AUTOTUNE ) return dataset # 加载数据集 train_ds = load_dataset(data_dir) val_ds = load_dataset(test_data_dir) # 批处理和预取 train_ds = train_ds.batch(batch_size).prefetch(tf.data.experimental.AUTOTUNE) val_ds = val_ds.batch(batch_size).prefetch(tf.data.experimental.AUTOTUNE) # 验证数据预处理是否正确 for images, labels in train_ds.take(1): # 检查图像标准化是否正确 min_value = tf.reduce_min(images) max_value = tf.reduce_max(images) print(f"图像标准化检查: 最小值 = {min_value.numpy()}, 最大值 = {max_value.numpy()}") assert min_value >= -1 and max_value <= 1, "图像标准化错误,范围应为[-1, 1]" # 检查标签是否为one-hot编码且正确 print("标签示例:", labels[0].numpy()) # 应为one-hot如[0,0,1,...,0] assert tf.reduce_sum(labels[0]).numpy() == 1, "标签应该是one-hot编码,其中只有一个值为1,其余为0" return train_ds, val_ds def model_load(IMG_SHAPE=(224, 224, 3), class_num=16, learning_rate=0.01): # 添加learning_rate参数 base_model = tf.keras.applications.MobileNetV2( input_shape=IMG_SHAPE, include_top=False, weights='imagenet' ) base_model.trainable = False model = tf.keras.Sequential([ base_model, tf.keras.layers.GlobalAveragePooling2D(), tf.keras.layers.Dense(class_num, activation='softmax') ]) # 显式设置学习率的优化器 optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate) model.compile( optimizer=optimizer, # 使用自定义优化器 loss='categorical_crossentropy', metrics=['accuracy'] ) model.summary() return model def show_loss_acc(history): acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] loss = history.history['loss'] val_loss = history.history['val_loss'] plt.figure(figsize=(8, 8)) plt.subplot(2, 1, 1) plt.plot(acc, label='Training Accuracy') plt.plot(val_acc, label='Validation Accuracy') plt.legend(loc='lower right') plt.ylabel('Accuracy') plt.ylim([min(plt.ylim()), 1]) plt.title('Training and Validation Accuracy') plt.subplot(2, 1, 2) plt.plot(loss, label='Training Loss') plt.plot(val_loss, label='Validation Loss') plt.legend(loc='upper right') plt.ylabel('Cross Entropy') plt.title('Training and Validation Loss') plt.xlabel('epoch') plt.savefig('results/results_mobilenet.png', dpi=100) def train(epochs): begin_time = time() # 创建必要目录 os.makedirs("models", exist_ok=True) os.makedirs("results", exist_ok=True) try: print("加载数据集中...") train_ds, val_ds = data_load( "C:/Users/dll20/Desktop/vegetables_tf2.3-master/new_data/train", "C:/Users/dll20/Desktop/vegetables_tf2.3-master/new_data/val", 224, 224, 16 ) # 验证数据加载 for images, labels in train_ds.take(1): print(f"图像形状: {images.shape}, 标签形状: {labels.shape}") print(f"标签示例: {labels[0].numpy()}") print("类别数量:", len(label_dict)) print("类别映射:", label_dict) model = model_load(class_num=len(label_dict)) print("开始训练...") history = model.fit( train_ds, validation_data=val_ds, epochs=epochs, verbose=1 ) model.save("models/mobilenet_engineer.h5") show_loss_acc(history) except Exception as e: print(f"训练出错: {str(e)}") import traceback traceback.print_exc() finally: print(f"总耗时: {time() - begin_time:.2f}秒") if __name__ == '__main__': # 配置TensorFlow tf.config.run_functions_eagerly(False) physical_devices = tf.config.list_physical_devices('GPU') if physical_devices: tf.config.experimental.set_memory_growth(physical_devices[0], True) 图像标准化检查: 最小值 = -1.0, 最大值 = 1.0 标签示例: [0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.] 图像形状: (16, 224, 224, 3), 标签形状: (16, 16) 标签示例: [0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.] 类别数量: 16 类别映射: {'electrodrill': 0, 'headphones': 1, 'keyboard': 2, 'mobile_phone': 3, 'monitor': 4, 'mouse': 5, 'multimeter': 6, 'number': 7, 'oscillograph': 8, 'pliers': 9, 'printer': 10, 'screwdriver': 11, 'soldering_iron': 12, 'speaker': 13, 'tape_measure': 14, 'wrench': 15} Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= mobilenetv2_1.00_224 (Functi (None, 7, 7, 1280) 2257984 _________________________________________________________________ global_average_pooling2d (Gl (None, 1280) 0 _________________________________________________________________ dense (Dense) (None, 16) 20496 ================================================================= Total params: 2,278,480 Trainable params: 20,496 Non-trainable params: 2,257,984 _________________________________________________________________ 开始训练... Epoch 1/100 2025-05-17 20:14:57.943383: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cublas64_10.dll 2025-05-17 20:16:05.881342: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cudnn64_7.dll 2025-05-17 20:19:28.437448: W tensorflow/stream_executor/gpu/redzone_allocator.cc:314] Internal: Invoking GPU asm compilation is supported on Cuda non-Windows platforms only Relying on driver to perform ptx compilation. Modify $PATH to customize ptxas location. This message will be only logged once. 1024/1024 [==============================] - 53s 52ms/step - loss: 9.9016 - accuracy: 0.0606 - val_loss: 9.3069 - val_accuracy: 0.0701 Epoch 2/100 1024/1024 [==============================] - 77s 75ms/step - loss: 10.5672 - accuracy: 0.0642 - val_loss: 10.8782 - val_accuracy: 0.0718 Epoch 3/100 1024/1024 [==============================] - 80s 78ms/step - loss: 10.6035 - accuracy: 0.0639 - val_loss: 10.8998 - val_accuracy: 0.0658 Epoch 4/100 1024/1024 [==============================] - 78s 76ms/step - loss: 10.4597 - accuracy: 0.0658 - val_loss: 9.5053 - val_accuracy: 0.0581 Epoch 5/100 1024/1024 [==============================] - 77s 75ms/step - loss: 10.1673 - accuracy: 0.0596 - val_loss: 12.2643 - val_accuracy: 0.0620 Epoch 6/100 1024/1024 [==============================] - 81s 79ms/step - loss: 10.1886 - accuracy: 0.0628 - val_loss: 9.2048 - val_accuracy: 0.0641 Epoch 7/100 1024/1024 [==============================] - 78s 76ms/step - loss: 10.2992 - accuracy: 0.0630 - val_loss: 10.0681 - val_accuracy: 0.0658 Epoch 8/100 1024/1024 [==============================] - 65s 63ms/step - loss: 10.2812 - accuracy: 0.0665 - val_loss: 12.2382 - val_accuracy: 0.0645 Epoch 9/100 1024/1024 [==============================] - 76s 74ms/step - loss: 11.4436 - accuracy: 0.0637 - val_loss: 9.5845 - val_accuracy: 0.0697 Epoch 10/100 1024/1024 [==============================] - 55s 54ms/step - loss: 10.2822 - accuracy: 0.0664 - val_loss: 9.9871 - val_accuracy: 0.0632 Epoch 11/100 1024/1024 [==============================] - 56s 55ms/step - loss: 10.9518 - accuracy: 0.0647 - val_loss: 12.8353 - val_accuracy: 0.0603 Epoch 12/100 1024/1024 [==============================] - 57s 55ms/step - loss: 10.7480 - accuracy: 0.0646 - val_loss: 10.8068 - val_accuracy: 0.0607 Epoch 13/100 1024/1024 [==============================] - 56s 54ms/step - loss: 10.3040 - accuracy: 0.0618 - val_loss: 11.6900 - val_accuracy: 0.0628 Epoch 14/100 1024/1024 [==============================] - 54s 52ms/step - loss: 10.5912 - accuracy: 0.0630 - val_loss: 14.3563 - val_accuracy: 0.0778 Epoch 15/100 1024/1024 [==============================] - 53s 52ms/step - loss: 10.7772 - accuracy: 0.0635 - val_loss: 11.0138 - val_accuracy: 0.0641 Epoch 16/100 1024/1024 [==============================] - 53s 52ms/step - loss: 10.1329 - accuracy: 0.0651 - val_loss: 11.0438 - val_accuracy: 0.0632 Epoch 17/100 1024/1024 [==============================] - 54s 52ms/step - loss: 10.4157 - accuracy: 0.0617 - val_loss: 11.4240 - val_accuracy: 0.0662 Epoch 18/100 1024/1024 [==============================] - 57s 55ms/step - loss: 10.4042 - accuracy: 0.0635 - val_loss: 11.6729 - val_accuracy: 0.0624 train(epochs=100) 我上述代码运行输出 一共16个类 正确率一直这么低 基本没变化 感觉就是没用上这个模型的感觉 不是微调的问题 我的目的是图像分类出16个种类 帮我检查这个代码 帮我找找原因
05-18
下面是我的代码: import os import cv2 import numpy as np import tensorflow as tf from tensorflow.keras import layers, models, applications from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras.callbacks import EarlyStopping from tensorflow.keras.optimizers.legacy import Adam from sklearn.model_selection import train_test_split import tensorflow_addons as tfa # 新增用于高级优化器 # 配置文件路径 YIZHUIHE_PATH = "yizhuihe" STATS_PATH = "zhuihetongji.xlsx" PREPROCESSED_DATA_PATH = "preprocessed_data4" # 保存预处理数据的目录 MODEL_PATH = "bamboo_matching_model4.h5" # 模型保存路径 EPOCHS = 10 BATCH_SIZE = 32 # 创建保存预处理数据的目录 os.makedirs(PREPROCESSED_DATA_PATH, exist_ok=True) # -------------------- 数据预处理模块 -------------------- class BambooPreprocessor: def __init__(self, target_size=(256, 64)): self.target_size = target_size self.region_size = (64, 64) def _enhance_texture(self, img): """增强竹简纹理特征""" # 转换为RGB格式保持一致性 img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 1. 自适应直方图均衡化 lab = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2LAB) l, a, b = cv2.split(lab) clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8)) l = clahe.apply(l) lab = cv2.merge((l, a, b)) enhanced = cv2.cvtColor(lab, cv2.COLOR_LAB2RGB) # 2. 纹理方向滤波 kernel = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) textured = cv2.filter2D(enhanced, -1, kernel) return textured def _detect_fracture(self, img): """改进的断口检测方法""" # 灰度化+二值化 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU) # 边缘检测(自适应阈值) low_thresh = np.percentile(gray, 25) high_thresh = np.percentile(gray, 75) edges = cv2.Canny(gray, low_thresh, high_thresh) # 轮廓分析(OpenCV版本兼容处理) if cv2.__version__.startswith('4'): contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) else: _, contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return None main_contour = max(contours, key=cv2.contourArea) # 提取边界区域 x, y, w, h = cv2.boundingRect(main_contour) boundary_width = 10 # 统一边界宽度 # 确保边界在图像范围内 top = img[max(y, 0):min(y+boundary_width, img.shape[0]), max(x, 0):min(x+boundary_width, img.shape[1])] bottom = img[max(y+h-boundary_width, 0):min(y+h, img.shape[0]), max(x, 0):min(x+boundary_width, img.shape[1])] left = img[max(y, 0):min(y+h, img.shape[0]), max(x, 0):min(x+boundary_width, img.shape[1])] right = img[max(y, 0):min(y+h, img.shape[0]), max(x+w-boundary_width, 0):min(x+w, img.shape[1])] # 方向特征 sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5) sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5) orientation = np.arctan2(sobely, sobelx) orientation_region = orientation[max(y, 0):min(y+h, img.shape[0]), max(x, 0):min(x+w, img.shape[1])] return { 'top': top, 'bottom': bottom, 'left': left, 'right': right, 'orientation': orientation_region } def preprocess(self, img_path): img = cv2.imread(img_path) if img is None: return None # 纹理增强 img = self._enhance_texture(img) # 提取断口区域 fracture_regions = self._detect_fracture(img) if not fracture_regions: return None # 统一所有区域的大小 resized_regions = {} for region_name in ['top', 'bottom', 'left', 'right']: region = fracture_regions[region_name] # 确保是单通道灰度图 if len(region.shape) == 3: region = cv2.cvtColor(region, cv2.COLOR_BGR2GRAY) resized_regions[region_name] = cv2.resize(region, self.region_size) # 处理方向特征图 orientation = fracture_regions['orientation'] orientation = cv2.normalize(orientation, None, 0, 255, cv2.NORM_MINMAX) orientation = cv2.resize(orientation, self.region_size) # 创建多通道特征图 channels = [ resized_regions['top'], resized_regions['bottom'], resized_regions['left'], resized_regions['right'], orientation ] # 堆叠通道并调整最终尺寸 processed = np.stack(channels, axis=-1) return cv2.resize(processed, self.target_size) # -------------------- # 数据加载器 # -------------------- class BambooDataset: def __init__(self, data_root): self.data_root = data_root self.groups = self._load_groups() self.preprocessor = BambooPreprocessor() def _load_groups(self): """加载已缀合组信息""" groups = {} for group_id in os.listdir(self.data_root): group_path = os.path.join(self.data_root, group_id) if os.path.isdir(group_path): groups[group_id] = [ os.path.join(group_path, f) for f in os.listdir(group_path) if f.endswith(('.jpg', '.png')) ] return groups def _generate_pairs(self): """生成训练样本对(正负样本)""" positive_pairs = [] negative_pairs = [] # 正样本:同组内竹简 for group_id, paths in self.groups.items(): if len(paths) < 2: continue for i in range(len(paths)): for j in range(i+1, len(paths)): positive_pairs.append((paths[i], paths[j], 1)) # 负样本:不同组竹简 all_paths = [p for paths in self.groups.values() for p in paths] group_ids = list(self.groups.keys()) # 平衡正负样本数量 num_neg = min(len(positive_pairs), len(all_paths) * 2) for _ in range(num_neg): while True: path1 = np.random.choice(all_paths) path2 = np.random.choice(all_paths) group1 = next(g for g, ps in self.groups.items() if path1 in ps) group2 = next(g for g, ps in self.groups.items() if path2 in ps) if group1 != group2: negative_pairs.append((path1, path2, 0)) break return positive_pairs + negative_pairs def load_dataset(self): """加载预处理后的数据集""" pairs = self._generate_pairs() X1, X2, y = [], [], [] for path1, path2, label in pairs: img1 = self.preprocessor.preprocess(path1) img2 = self.preprocessor.preprocess(path2) if img1 is not None and img2 is not None: X1.append(img1) X2.append(img2) y.append(label) return np.array(X1), np.array(X2), np.array(y) def create_improved_siamese_network(input_shape): """改进的孪生网络架构""" def spatial_attention(input_tensor): """空间注意力机制""" avg_pool = layers.Lambda(lambda x: tf.reduce_mean(x, axis=3, keepdims=True))(input_tensor) max_pool = layers.Lambda(lambda x: tf.reduce_max(x, axis=3, keepdims=True))(input_tensor) concat = layers.Concatenate(axis=3)([avg_pool, max_pool]) cbam_feature = layers.Conv2D(1, kernel_size=7, padding='same', activation='sigmoid')(concat) return layers.Multiply()([input_tensor, cbam_feature]) # 输入层 base_input = layers.Input(shape=input_shape) # 通道适配层:将5通道转换为3通道 x = layers.Conv2D(3, (1, 1), padding='same', name='channel_adapter')(base_input) # 共享特征提取器(使用ResNet50) base_model = applications.ResNet50( weights='imagenet', include_top=False, input_shape=(input_shape[0], input_shape[1], 3) ) x = base_model(x) # 添加注意力机制 x = spatial_attention(x) # 多尺度特征融合 branch1 = layers.GlobalAveragePooling2D()(x) branch2 = layers.GlobalMaxPooling2D()(x) x = layers.Concatenate()([branch1, branch2]) # 增强特征表示 x = layers.Dense(512, activation='relu', kernel_regularizer=tf.keras.regularizers.l1_l2(0.01, 0.01))(x) x = layers.Dropout(0.3)(x) feature_extractor = models.Model(inputs=base_input, outputs=x) # 孪生架构 input_a = layers.Input(shape=input_shape) input_b = layers.Input(shape=input_shape) features_a = feature_extractor(input_a) features_b = feature_extractor(input_b) # 改进的特征差异度量 diff = layers.Subtract()([features_a, features_b]) abs_diff = layers.Lambda(lambda x: tf.abs(x))(diff) squared_diff = layers.Lambda(lambda x: tf.square(x))(diff) concat_diff = layers.Concatenate()([abs_diff, squared_diff]) # 相似性分类 x = layers.Dense(256, activation='relu')(concat_diff) x = layers.Dropout(0.2)(x) classification_output = layers.Dense(1, activation='sigmoid', name='classification')(x) # 添加特征差异作为额外输出 feat_diff = layers.Lambda( lambda x: tf.reduce_mean(tf.abs(x), axis=1), name='feature_difference' )(concat_diff) # 创建具有两个输出的模型 siamese_model = models.Model( inputs=[input_a, input_b], outputs=[classification_output, feat_diff] ) return siamese_model # 配对数据增强生成器 class PairedDataGenerator: def __init__(self, X1, X2, y, datagen, batch_size=32): self.X1 = X1 self.X2 = X2 self.y = y self.datagen = datagen self.batch_size = batch_size # 初始化数据生成器 self.genX1 = datagen.flow(X1, y, batch_size=batch_size, shuffle=False) self.genX2 = datagen.flow(X2, y, batch_size=batch_size, shuffle=False) def __iter__(self): return self def __next__(self): X1_batch, y_batch = next(self.genX1) X2_batch, _ = next(self.genX2) return [X1_batch, X2_batch], y_batch # 困难样本挖掘回调 class HardExampleMiner(tf.keras.callbacks.Callback): def __init__(self, train_data, threshold=0.2): self.X1_train, self.X2_train, self.y_train = train_data self.threshold = threshold def on_epoch_end(self, epoch, logs=None): # 获取当前批次预测结果 y_pred, _ = self.model.predict([self.X1_train, self.X2_train], verbose=0) # 选择预测概率接近0.5的困难样本 hard_indices = np.where(np.abs(y_pred.squeeze() - 0.5) < self.threshold)[0] # 增强训练(仅训练困难样本) if len(hard_indices) > 0: self.model.fit( [self.X1_train[hard_indices], self.X2_train[hard_indices]], [self.y_train[hard_indices], np.zeros(len(hard_indices))], # 为特征差异输出提供伪标签 epochs=1, batch_size=BATCH_SIZE, verbose=0 ) def hybrid_loss(y_true, y_pred): """混合损失函数 - 同时处理分类输出和特征差异""" # 解包预测值:y_pred 包含两个输出 classification_output = y_pred[0] feat_diff = y_pred[1] # 确保y_true是正确形状 (batch_size, 1) y_true = tf.reshape(tf.cast(y_true, tf.float32), [-1, 1]) # 计算二元交叉熵损失 - 确保维度匹配 bce = tf.keras.losses.binary_crossentropy( y_true, classification_output, from_logits=False ) # 特征差异正则化 - 确保维度匹配 reg_loss = 0.1 * tf.maximum(0.5 - feat_diff, 0) return bce + reg_loss def train_and_evaluate(): # 检查预处理数据文件是否存在 x1_path = os.path.join(PREPROCESSED_DATA_PATH, "X1.npy") x2_path = os.path.join(PREPROCESSED_DATA_PATH, "X2.npy") y_path = os.path.join(PREPROCESSED_DATA_PATH, "y.npy") if os.path.exists(x1_path) and os.path.exists(x2_path) and os.path.exists(y_path): # 加载预处理数据 X1 = np.load(x1_path) X2 = np.load(x2_path) y = np.load(y_path) print("预处理数据已加载") else: # 加载并预处理数据 dataset = BambooDataset(YIZHUIHE_PATH) X1, X2, y = dataset.load_dataset() # 保存预处理数据 np.save(x1_path, X1) np.save(x2_path, X2) np.save(y_path, y) print("预处理数据已保存") # 划分数据集 X1_train, X1_val, X2_train, X2_val, y_train, y_val = train_test_split( X1, X2, y, test_size=0.2, random_state=42 ) # 数据增强配置 datagen = ImageDataGenerator( rotation_range=10, width_shift_range=0.1, height_shift_range=0.1, shear_range=0.1, zoom_range=0.1, horizontal_flip=True, fill_mode='nearest' ) # 创建配对数据生成器 train_generator = PairedDataGenerator( X1_train, X2_train, y_train, datagen, batch_size=BATCH_SIZE ) # 创建模型 siamese_model = create_improved_siamese_network(X1_train.shape[1:]) # 优化器(使用Lookahead优化器提升收敛性) optimizer = tfa.optimizers.Lookahead( Adam(learning_rate=1e-4), sync_period=6, slow_step_size=0.5 ) # 编译模型 - 使用自定义混合损失函数 siamese_model.compile( optimizer=optimizer, loss=hybrid_loss, metrics={'classification': 'accuracy'} # 只为分类输出计算准确率 ) # 早停策略 - 监控分类输出的准确率 early_stopping = EarlyStopping( monitor='val_classification_accuracy', patience=10, restore_best_weights=True, min_delta=0.001 ) # 困难样本挖掘 hard_miner = HardExampleMiner( train_data=(X1_train, X2_train, y_train), threshold=0.2 ) # 模型训练 - 注意:验证数据需要两个输出 history = siamese_model.fit( train_generator, steps_per_epoch=len(X1_train) // BATCH_SIZE, validation_data=([X1_val, X2_val], [y_val, np.zeros(len(y_val))]), # 为特征差异输出提供伪标签 epochs=EPOCHS, callbacks=[early_stopping, hard_miner], class_weight={0: 1.0, 1: 1.5} ) # 保存模型 siamese_model.save(MODEL_PATH) # 模型评估 - 只关注分类输出 loss = siamese_model.evaluate([X1_val, X2_val], [y_val, np.zeros(len(y_val))]) # 损失函数返回总损失,但我们关心分类准确率 # 在评估中,metrics 会返回分类准确率 print(f"验证准确率: {history.history['val_classification_accuracy'][-1]*100:.2f}%") return history if __name__ == "__main__": train_and_evaluate()在训练完毕后遇到了报错ifference_loss: 1.1556 - classification_accuracy: 0.4956 - val_loss: 36.8123 - val_classification_loss: 0.6945 - val_feature_difference_loss: 0.1284 - val_classification_accuracy: 0.4487 Epoch 10/10 1/32 [..............................] - ETA: 6:00 - loss: 30.5024 - classification_loss: 0.8720 - feature_differ 2/32 [>.............................] - ETA: 6:02 - loss: 30.2336 - classification_loss: 0.8529 - feature_differ 3/32 [=>............................] - ETA: 5:56 - loss: 30.5036 - classification_loss: 0.8665 - feature_differ 4/32 [==>...........................] - ETA: 5:47 - loss: 30.2310 - classification_loss: 0.8640 - feature_differ 5/32 [===>..........................] - ETA: 5:35 - loss: 29.9351 - classification_loss: 0.8612 - feature_differ 6/32 [====>.........................] - ETA: 5:23 - loss: 29.8819 - classification_loss: 0.8636 - feature_differ 7/32 [=====>........................] - ETA: 5:11 - loss: 29.8167 - classification_loss: 0.8773 - feature_differ 8/32 [======>.......................] - ETA: 4:58 - loss: 29.7443 - classification_loss: 0.9530 - feature_differ 9/32 [=======>......................] - ETA: 4:39 - loss: 29.6304 - classification_loss: 0.9469 - feature_differ10/32 [========>.....................] - ETA: 4:27 - loss: 29.4564 - classification_loss: 0.9363 - feature_differ11/32 [=========>....................] - ETA: 4:16 - loss: 29.2758 - classification_loss: 0.9282 - feature_differ12/32 [==========>...................] - ETA: 4:04 - loss: 29.1919 - classification_loss: 0.9231 - feature_differ13/32 [===========>..................] - ETA: 3:53 - loss: 29.1008 - classification_loss: 0.9268 - feature_differ14/32 [============>.................] - ETA: 3:41 - loss: 28.9858 - classification_loss: 0.9246 - feature_differ15/32 [=============>................] - ETA: 3:29 - loss: 28.8968 - classification_loss: 0.9279 - feature_differ16/32 [==============>...............] - ETA: 3:17 - loss: 28.7870 - classification_loss: 0.9224 - feature_differ17/32 [==============>...............] - ETA: 3:05 - loss: 28.6540 - classification_loss: 0.9196 - feature_differ18/32 [===============>..............] - ETA: 2:53 - loss: 28.5789 - classification_loss: 0.9091 - feature_differ19/32 [================>.............] - ETA: 2:41 - loss: 28.4827 - classification_loss: 0.9090 - feature_differ20/32 [=================>............] - ETA: 2:30 - loss: 28.3714 - classification_loss: 0.9066 - feature_differ21/32 [==================>...........] - ETA: 2:17 - loss: 28.2615 - classification_loss: 0.9061 - feature_differ22/32 [===================>..........] - ETA: 2:05 - loss: 28.1563 - classification_loss: 0.9246 - feature_differ23/32 [====================>.........] - ETA: 1:52 - loss: 28.0344 - classification_loss: 0.9217 - feature_differ24/32 [=====================>........] - ETA: 1:40 - loss: 27.9423 - classification_loss: 0.9150 - feature_differ25/32 [======================>.......] - ETA: 1:27 - loss: 27.8502 - classification_loss: 0.9217 - feature_differ26/32 [=======================>......] - ETA: 1:15 - loss: 27.7519 - classification_loss: 0.9186 - feature_differ27/32 [========================>.....] - ETA: 1:02 - loss: 27.6517 - classification_loss: 0.9175 - feature_differ28/32 [=========================>....] - ETA: 50s - loss: 27.5349 - classification_loss: 0.9154 - feature_differe29/32 [==========================>...] - ETA: 37s - loss: 27.4168 - classification_loss: 0.9140 - feature_differe30/32 [===========================>..] - ETA: 25s - loss: 27.3513 - classification_loss: 0.9132 - feature_differe31/32 [============================>.] - ETA: 12s - loss: 27.2566 - classification_loss: 0.9135 - feature_differe32/32 [==============================] - ETA: 0s - loss: 27.1861 - classification_loss: 0.9117 - feature_difference_loss: 1.1294 - classification_accuracy: 0.4956 2025-06-22 14:05:17.364362: W tensorflow/core/framework/op_kernel.cc:1839] OP_REQUIRES failed at fused_batch_norm_op.cc:1565 : RESOURCE_EXHAUSTED: OOM when allocating tensor with shape[32,4,16,1024] and type float on /job:localhost/replica:0/task:0/device:CPU:0 by allocator cpu 2025-06-22 14:05:17.396860: W tensorflow/core/framework/op_kernel.cc:1839] OP_REQUIRES failed at conv_ops_fused_impl.h:772 : RESOURCE_EXHAUSTED: OOM when allocating tensor with shape[32,4,16,1024] and type float on /job:localhost/replica:0/task:0/device:CPU:0 by allocator cpu Traceback (most recent call last): File "c:\Users\lin13\Desktop\data\lab9-8.py", line 436, in <module> train_and_evaluate() File "c:\Users\lin13\Desktop\data\lab9-8.py", line 415, in train_and_evaluate history = siamese_model.fit( File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler raise e.with_traceback(filtered_tb) from None File "c:\Users\lin13\Desktop\data\lab9-8.py", line 310, in on_epoch_end self.model.fit( tensorflow.python.framework.errors_impl.ResourceExhaustedError: Graph execution error: Detected at node model_1/model/resnet50/conv4_block6_3_bn/FusedBatchNormV3 defined at (most recent call last): File "c:\Users\lin13\Desktop\data\lab9-8.py", line 436, in <module> File "c:\Users\lin13\Desktop\data\lab9-8.py", line 415, in train_and_evaluate File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 1850, in fit File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\callbacks.py", line 453, in on_epoch_end File "c:\Users\lin13\Desktop\data\lab9-8.py", line 310, in on_epoch_end File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 1783, in fit File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 1377, in train_function File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 1360, in step_function File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 1349, in run_step File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 1126, in train_step File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 589, in __call__ File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\base_layer.py", line 1149, in __call__ File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 96, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\functional.py", line 515, in call File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\functional.py", line 672, in _run_internal_graph File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 589, in __call__ File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\base_layer.py", line 1149, in __call__ File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 96, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\functional.py", line 515, in call File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\functional.py", line 672, in _run_internal_graph File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\training.py", line 589, in __call__ File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\base_layer.py", line 1149, in __call__ File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 96, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\functional.py", line 515, in call File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\functional.py", line 672, in _run_internal_graph File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 65, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\engine\base_layer.py", line 1149, in __call__ File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\traceback_utils.py", line 96, in error_handler File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\layers\normalization\batch_normalization.py", line 597, in call File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\layers\normalization\batch_normalization.py", line 990, in _fused_batch_norm File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\utils\control_flow_util.py", line 108, in smart_cond File "C:\Users\lin13\AppData\Local\Programs\Python\Python39\lib\site-packages\keras\src\layers\normalization\batch_normalization.py", line 964, in _fused_batch_norm_training OOM when allocating tensor with shape[32,4,16,1024] and type float on /job:localhost/replica:0/task:0/device:CPU:0 by allocator cpu [[{{node model_1/model/resnet50/conv4_block6_3_bn/FusedBatchNormV3}}]] Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info. This isn't available when running in Eager mode. [Op:__inference_train_function_66233] 2025-06-22 14:05:32.873794: W tensorflow/core/kernels/data/generator_dataset_op.cc:108] Error occurred when finalizing GeneratorDataset iterator: FAILED_PRECONDITION: Python interpreter state is not initialized. The process may be terminated. [[{{node PyFunc}}]] PS C:\Users\lin13\Desktop\data> 帮我看看为什么
06-23
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值