全部產品
Search
文件中心

Platform For AI:TensorFlow常見問題

更新時間:Mar 13, 2025

本文為您介紹TensorFlow的相關問題。

目錄

如何支援多Python檔案引用?

您可以通過Python檔案組織訓練指令碼。通常首先將資料預先處理邏輯存放在某個Python檔案中,然後將模型定義在另一個Python檔案中,最後通過一個Python檔案串聯整個訓練過程。例如,在test1.py中定義函數,如果test2.py檔案需要使用test1.py中的函數,且將test2.py作為程式入口檔案,則只需要將test1.py和test2.py打包為.tar.gz包並上傳即可,如下圖所示。多指令碼引用其中:

  • Python代碼檔案:.tar.gz包。

  • Python主檔案:入口程式檔案。

如何上傳資料到OSS?

深度學習演算法的資料存放區在OSS的Bucket中,因此需要先建立OSS Bucket。建議您將OSS Bucket建立在與深度學習GPU叢集相同的地區,從而使用阿里雲傳統網路進行資料轉送,進而使演算法運行免收流量費。建立OSS Bucket後,可以在OSS管理主控台建立檔案夾、組織資料目錄或上傳資料。

您可以通過API或SDK上傳資料至OSS,詳情請參見簡單上傳。同時,OSS提供了大量工具(工具列表請參見OSS常用工具匯總。)協助您更高效地完成任務,建議使用ossutil或osscmd工具上傳下載檔案。

說明

使用工具上傳檔案時,需要配置AccessKey ID和AccessKey Secret,您可以登入阿里雲管理主控台建立或查看該資訊。

如何讀取OSS資料?

Python不支援讀取OSS資料,因此所有調用Python Open()os.path.exist()等檔案和檔案夾操作函數的代碼都無法執行。例如Scipy.misc.imread()numpy.load()等。

通常採用以下兩種方式在PAI中讀取資料:

  • 使用tf.gfile下的函數,適用於簡單讀取一張圖片或一個文本等。成員函數如下。

    tf.gfile.Copy(oldpath, newpath, overwrite=False) # 拷貝檔案。
    tf.gfile.DeleteRecursively(dirname) # 遞迴刪除目錄下所有檔案。
    tf.gfile.Exists(filename) # 檔案是否存在。
    tf.gfile.FastGFile(name, mode='r') # 無阻塞讀取檔案。
    tf.gfile.GFile(name, mode='r') # 讀取檔案。
    tf.gfile.Glob(filename) # 列出檔案夾下所有檔案, 支援Pattern。
    tf.gfile.IsDirectory(dirname) # 返回dirname是否為一個目錄
    tf.gfile.ListDirectory(dirname) # 列出dirname下所有檔案。
    tf.gfile.MakeDirs(dirname) # 在dirname下建立一個檔案夾。如果父目錄不存在, 則自動建立父目錄。如果檔案夾已經存在, 且檔案夾可寫, 則返回成功。
    tf.gfile.MkDir(dirname) # 在dirname處建立一個檔案夾。
    tf.gfile.Remove(filename) # 刪除filename。
    tf.gfile.Rename(oldname, newname, overwrite=False) # 重新命名。
    tf.gfile.Stat(dirname) # 返回目錄的統計資料。
    tf.gfile.Walk(top, inOrder=True) # 返回目錄的檔案樹。
  • 使用tf.gfile.Globtf.gfile.FastGFiletf.WholeFileReader()tf.train.shuffle_batch(),適用於批量讀取檔案(讀取檔案之前需要擷取檔案清單。如果批量讀取,還需要建立Batch)。

使用Designer搭建深度學習實驗時,通常需要在介面右側設定讀取目錄及代碼檔案等參數。tf.flags支援通過-XXX(XXX表示字串)的形式傳入該參數。

import tensorflow as tf
FLAGS = tf.flags.FLAGS
tf.flags.DEFINE_string('buckets', 'oss://{OSS Bucket}/', '訓練圖片所在檔案夾')
tf.flags.DEFINE_string('batch_size', '15', 'batch大小')
files = tf.gfile.Glob(os.path.join(FLAGS.buckets,'*.jpg')) # 列出buckets下所有JPG檔案路徑。

批量讀取檔案時,對於不同規模的檔案,建議分別使用如下方式:

  • 讀取小規模檔案時,建議使用tf.gfile.FastGfile()

    for path in files:
        file_content = tf.gfile.FastGFile(path, 'rb').read() # 一定記得使用rb讀取, 否則很多情況下都會報錯。
        image = tf.image.decode_jpeg(file_content, channels=3) # 以JPG圖片為例。
  • 讀取大規模檔案時,建議使用tf.WholeFileReader()

    reader = tf.WholeFileReader()  # 執行個體化reader。
    fileQueue = tf.train.string_input_producer(files)  # 建立一個供reader讀取的隊列。
    file_name, file_content = reader.read(fileQueue)  # 使reader從隊列中讀取一個檔案。
    image_content = tf.image.decode_jpeg(file_content, channels=3)  # 將讀取結果解碼為圖片。
    label = XXX  # 省略處理label的過程。
    batch = tf.train.shuffle_batch([label, image_content], batch_size=FLAGS.batch_size, num_threads=4,
                                   capacity=1000 + 3 * FLAGS.batch_size, min_after_dequeue=1000)
    sess = tf.Session()  # 建立Session。
    tf.train.start_queue_runners(sess=sess)  # 啟動隊列。如果未執行該命令,則線程會一直阻塞。
    labels, images = sess.run(batch)  # 擷取結果。

    核心代碼解釋如下:

    • tf.train.string_input_producer:將files轉換為隊列,且需要使用tf.train.start_queue_runners啟動隊列。

    • tf.train.shuffle_batch參數如下:

      • batch_size:批處理大小,即每次運行Batch返回的資料數量。

      • num_threads:運行線程數,一般設定為4。

      • capacity:隨機取檔案範圍。例如,資料集有10000個資料,如果需要從5000個資料中隨機抽取,則將capacity配置為5000。

      • min_after_dequeue:維持隊列的最小長度,不能大於capacity

如何為OSS寫入資料?

您可以通過以下任意一種方式將資料寫入OSS中,產生的檔案儲存體在輸出目錄/model/example.txt

  • 通過tf.gfile.FastGFile()寫入,樣本如下。

    tf.gfile.FastGFile(FLAGS.checkpointDir + 'example.txt', 'wb').write('hello world')
  • 通過tf.gfile.Copy()拷貝,樣本如下。

    tf.gfile.Copy('./example.txt', FLAGS.checkpointDir + 'example.txt')

為什麼運行過程中出現OOM?

使用的記憶體達到上限30 GB,建議通過gfile讀取OSS資料,詳情請參見如何讀取OSS資料?

TensorFlow有哪些案例?

    使用TensorFlow自動寫歌,詳情請參見寫歌案例

    配置兩個GPU時,model_average_iter_interval有什麼作用?

    如果未配置model_average_iter_interval參數,則GPU會運行標準的Parallel-SGD,每個迭代都會交換梯度更新。如果model_average_iter_interval大於1,則使用Model Average方法,訓練迭代間隔若干輪(model_average_iter_interval表示數值輪數)計算兩個平均模型參數。

    TensorFlow模型如何匯出為SavedModel?

    SavedModel格式

    使用EAS預置官方Processor將TensorFlow模型部署為線上服務,必須先將模型匯出為官方定義的SavedModel格式(TensorFlow官方推薦的匯出模型格式)。SavedModel模型格式的目錄結構如下。

    assets/
    variables/
        variables.data-00000-of-00001
        variables.index
    saved_model.pb|saved_model.pbtxt

    其中:

    • assets表示一個可選目錄,用於儲存預測時的輔助文檔資訊。

    • variables儲存tf.train.Saver儲存的變數資訊。

    • saved_model.pbsaved_model.pbtxt儲存MetaGraphDef(儲存訓練預測模型的程式邏輯)和SignatureDef(用於標記預測時的輸入和輸出)。

    匯出SavedModel

    使用TensorFlow匯出SavedModel格式的模型請參見Saving and Restoring。如果模型比較簡單,則可以使用如下方式快速匯出SavedModel。

    tf.saved_model.simple_save(
      session,
      "./savedmodel/",
      inputs={"image": x},   ## x表示模型的輸入變數。
      outputs={"scores": y}  ## y表示模型的輸出。
    )

    請求線上預測服務時,請求中需要指定模型signature_name,使用simple_save()方法匯出的模型中,signature_name預設為serving_default

    如果模型比較複雜,則可以使用手工方式匯出SavedModel,程式碼範例如下。

    print('Exporting trained model to', export_path)
    builder = tf.saved_model.builder.SavedModelBuilder(export_path)
    tensor_info_x = tf.saved_model.utils.build_tensor_info(x)
    tensor_info_y = tf.saved_model.utils.build_tensor_info(y)
    
    prediction_signature = (
        tf.saved_model.signature_def_utils.build_signature_def(
            inputs={'images': tensor_info_x},
            outputs={'scores': tensor_info_y},
            method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME)
    )
    
    legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op')
    
    builder.add_meta_graph_and_variables(
        sess, [tf.saved_model.tag_constants.SERVING],
        signature_def_map={
            'predict_images': prediction_signature,
        },
        legacy_init_op=legacy_init_op
    )
    
    builder.save()
    print('Done exporting!')

    其中:

    • export_path表示匯出模型的路徑。

    • prediction_signature表示模型為輸入和輸出構建的SignatureDef,詳情請參見SignatureDef。樣本中的signature_name為predict_images

    • builder.add_meta_graph_and_variables方法表示匯出模型的參數。

    說明
    • 匯出預測所需的模型時,必須指定匯出模型的Tag為tf.saved_model.tag_constants.SERVING。

    • 有關TensorFlow模型的更多資訊,請參見TensorFlow SavedModel

    Keras模型轉換為SavedModel

    使用Keras的model.save()方法會將Keras模型匯出為H5格式,需要將其轉換為SavedModel才能進行線上預測。您可以先調用load_model()方法載入H5模型,再將其匯出為SavedModel格式,程式碼範例如下。

    import tensorflow as tf
    with tf.device("/cpu:0"):
        model = tf.keras.models.load_model('./mnist.h5')
        tf.saved_model.simple_save(
          tf.keras.backend.get_session(),
          "./h5_savedmodel/",
          inputs={"image": model.input},
          outputs={"scores": model.output}
        )

    Checkpoint轉換為Savedmodel

    訓練過程中使用tf.train.Saver()方法儲存的模型格式為checkpoint,需要將其轉換為SavedModel才能進行線上預測。您可以先調用saver.restore()方法將Checkpoint載入為tf.Session,再將其匯出為SavedModel格式,程式碼範例如下。

    import tensorflow as tf
    # variable define ...
    saver = tf.train.Saver()
    with tf.Session() as sess:
      # Initialize v1 since the saver will not.
        saver.restore(sess, "./lr_model/model.ckpt")
        tensor_info_x = tf.saved_model.utils.build_tensor_info(x)
        tensor_info_y = tf.saved_model.utils.build_tensor_info(y)
        tf.saved_model.simple_save(
          sess,
          "./savedmodel/",
          inputs={"image": tensor_info_x},
          outputs={"scores": tensor_info_y}
        )