歡迎光臨
每天分享高質量文章

ICME 2019短視頻內容理解與推薦競賽正式啟動(附baseline方法)

想到推薦演算法,大家可能會想到電商和游戲。不過,隨著短視頻產品的崛起,推薦演算法也迎來一個新的風口,被大量應用在短視頻領域,吸引更多的用戶看到自己喜歡的內容。 

 

2019 年 2 月,ICME 2019 短視頻內容理解與推薦競賽正式開放提交。本次比賽掛靠多媒體領域的頂會 IEEE ICME,主題為預測用戶是否看完及點贊一個短視頻。 

 

比賽鏈接:

 

https://biendata.com/competition/icmechallenge2019/ 

 

比賽獎金:2 萬美元 

 

時間:2019 年 2 月 11 日 – 2019 年 4 月 7 日

 

背景

 

“一圖勝千言”,僅僅一張圖片就包含大量信息,難以用幾個詞來描述。更不用說短視頻了。所以,雖然機器學習近年來在圖像識別、語音識別等領域取得了重大進步,但在視頻內容理解領域仍有許多問題需要探索。 

 

不過,目前也有不少相關研究。2016 年,谷歌 YouTube 團隊在 ACM RecSys  會議上發表論文 Deep Neural Networks for YouTube Recommendations,詳細介紹了不少 YouTube 視頻推薦功能的技術細節。

 

比賽資料與賽道

為了方便大家參賽,ICME 2019 短視頻內容理解與推薦競賽的主辦方已經提取出了多種型別的短視頻內容特征,包括視覺特征、文本特征和音頻特征。 

 

此外,為了方便不同背景的參賽者參加比賽,本次比賽按照資料量分成兩個賽道(資料格式和預測任務都相同): 

 

賽道 1:大規模資料集,億級別的資料信息。 

 

賽道2:小規模資料集,千萬級別的資料信息。

 

評測方法


參賽選手需要預測測試資料中每一條資料的點擊(finish+like)概率。本次比賽使用 AUC(ROC 曲線下麵積)作為評估指標。AUC 越高,代表結果越優,排名越靠前。在總分中,finish 和 like 的分配比例是:0.7*finish+0.3*like。

 

Baseline代碼

 

在 TRACK 2 上,baseline 的結果分別為 like:86.5%,finish:69.8%。 

 

Baseline 需要 TensorFlow 1.12.0。模型下載地址:

 

https://github.com/challenge-ICME2019-Bytedance/Bytedance_ICME_challenge

baseline腳本 & 代碼說明

#——運行腳本——#
train.sh  

#——訓練模型——#
train.py  

#——模型引數輸入——#
common/  
model_args.py  

#——tensorflow資料轉換輸入——#
data_io/  
data_parser.py  

#——模型準備與框架搭建——#
models/  
model.py  

#——fm推薦演算法——#
model_zoo/  
fm.py

#--utils資料處理——#
utils/  
utils.py

Bytedance_ICME_challenge/model_zoo/fm.py

import tensorflow as tf
 
class FMModelParams(object):
  """初始化fm模型權重"""
  def __init__(self, feature_size, embedding_size):
    self._feature_size = feature_size
    self._embedding_size = embedding_size
 
  def initialize_weights(self):
    """ 初始化fm權重
    Returns
    weights:
      feature_embeddings:  vi, vj second order params
      weights_first_order: wi first order params
      bias: b  bias
    """
 
    weights = dict()
    weights_initializer=tf.glorot_normal_initializer()
    bias_initializer=tf.constant_initializer(0.0)
    weights["feature_embeddings"] = tf.get_variable(
        name='weights',
        dtype=tf.float32,
        initializer=weights_initializer,
        shape=[self._feature_size, self._embedding_size])
    weights["weights_first_order"] = tf.get_variable(
        name='vectors',
        dtype=tf.float32,
        initializer=weights_initializer,
        shape=[self._feature_size, 1])
    weights["fm_bias"] = tf.get_variable(
        name='bias',
        dtype=tf.float32,
        initializer=bias_initializer,
        shape=[1])
    return weights
 
class FMModel(object):
  """fm實施"""
 
  @staticmethod
  def fm_model_fn(features, labels, mode, params):
    """建立tensorflow模型"""
 
    #解析引數
    embedding_size = params['embedding_size']
    feature_size = params['feature_size']
    batch_size = params['batch_size']
    learning_rate = params['learning_rate']
    field_size = params['field_size']
    optimizer_used = params['optimizer']
 
    #解析特征
    feature_idx = features["feature_idx"]
    feature_idx = tf.reshape(feature_idx, shape=[batch_size, field_size])
    labels = tf.reshape(labels, shape=[batch_size, 1])
    feature_values = features["feature_values"]
    feature_values = tf.reshape(feature_values, shape=[batch_size, field_size, 1])
 
    # tensorflow fm 權重
    tf_model_params = FMModelParams(feature_size, embedding_size)
    weights = tf_model_params.initialize_weights()
    embeddings = tf.nn.embedding_lookup(
        weights["feature_embeddings"],
        feature_idx
        )
    weights_first_order = tf.nn.embedding_lookup(
        weights["weights_first_order"],
        feature_idx
        )
    bias = weights['fm_bias']
 
    #構建函式
    ##first order
    first_order = tf.multiply(feature_values, weights_first_order)
    first_order = tf.reduce_sum(first_order, 2)
    first_order = tf.reduce_sum(first_order, 1, keepdims=True)
 
    ##second order
    ### feature * embeddings
    f_e_m = tf.multiply(feature_values, embeddings)
    ###  square(sum(feature * embedding))
    f_e_m_sum = tf.reduce_sum(f_e_m, 1)
    f_e_m_sum_square = tf.square(f_e_m_sum)
    ###  sum(square(feature * embedding))
    f_e_m_square = tf.square(f_e_m)
    f_e_m_square_sum = tf.reduce_sum(f_e_m_square, 1)
 
    second_order = f_e_m_sum_square - f_e_m_square_sum
 
    second_order = tf.reduce_sum(second_order, 1, keepdims=True)
 
    ##最終標的函式
    logits = second_order + first_order + bias
    predicts = tf.sigmoid(logits)
 
    ##損失函式
    sigmoid_loss = tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=labels)
    sigmoid_loss = tf.reduce_mean(sigmoid_loss)
    loss = sigmoid_loss
 
    #訓練操作
    if optimizer_used == 'adagrad':
      optimizer = tf.train.AdagradOptimizer(
          learning_rate=learning_rate,
          initial_accumulator_value=1e-8)
    elif optimizer_used == 'adam':
      optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
    else:
      raise Exception("unknown optimizer", optimizer_used)
 
    train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step())
 
 
    #計算auc
    eval_metric_ops = {
        "auc": tf.metrics.auc(labels, predicts)
        }
    predictions = {"prob": predicts}
 
    return tf.estimator.EstimatorSpec(
        mode=tf.estimator.ModeKeys.TRAIN,
        predictions=predicts,
        loss=loss,
        eval_metric_ops=eval_metric_ops,
        train_op=train_op)

Bytedance_ICME_challenge/models/model.py

 

""" import necessary packages"""
import tensorflow as tf
from data_io.data_parser import PosShifts, LineParser
from model_zoo.fm import FMModel
 
 
class RecommendModelHandler(object):
  """設定推薦模型的類"""
  def __init__(self, train_dataset_path, val_dataset_path, save_model_dir,  \
      learning_rate=0.1, num_threads=1, num_epochs=100, batch_size=40,  \
      embedding_size=100, optimizer='adam', task="finish", track=2):
    """初始化基本引數"""
    self._learning_rate = learning_rate
    self._num_threads = num_threads
    self._num_epochs = num_epochs
    self._batch_size = batch_size
    self._train_dataset_path = train_dataset_path
    self._val_dataset_path = val_dataset_path
    self._save_model_dir = save_model_dir
    self._embedding_size = embedding_size
    self._optimizer = optimizer
    self._task = task
    self._track = track
 
 
  def build_model(self):
    """建立推薦模型框架"""
    config = tf.estimator.RunConfig().replace(
        session_config=tf.ConfigProto(device_count={'CPU':self._num_threads}),
        log_step_count_steps=20)
    PosShifts(self._track)
    feature_size = PosShifts.get_features_num()
    params={
        'feature_size': feature_size,
        'embedding_size': self._embedding_size,
        'learning_rate': self._learning_rate,
        'field_size'5,
        'batch_size': self._batch_size,
        'optimizer': self._optimizer}
 
    model = tf.estimator.Estimator(
        model_fn=FMModel.fm_model_fn,
        model_dir=self._save_model_dir,
        params=params,
        config=config)
    return model
 
  def prepare_data_fn(self, data_mode='train'):
    """準備訓練/驗證資料"""
    if data_mode == 'train':
      dataset = tf.data.TextLineDataset(self._train_dataset_path)
    elif data_mode == 'val':
      dataset = tf.data.TextLineDataset(self._val_dataset_path)
    else:
      raise Exception("unknown data_mode", data_mode)
 
    if self._task == "finish":
      dataset = dataset.map(LineParser.parse_finish_line)
    elif self._task == "like":
      dataset = dataset.map(LineParser.parse_like_line)
    else:
      raise Exception("unknown task", task)
 
    dataset = dataset.shuffle(buffer_size=300)
    dataset = dataset.repeat(self._num_epochs)
    dataset = dataset.batch(self._batch_size)
    data_iterator = dataset.make_one_shot_iterator()
    idx, features, labels = data_iterator.get_next()
    feature_infos = {}
    feature_infos['feature_idx'] = idx
    feature_infos['feature_values'] = features
    tf.logging.info(labels)
    return feature_infos, labels
 
 
  def train(self):
    """訓練模型"""
    model = self.build_model()
    train_spec = tf.estimator.TrainSpec(input_fn=lambda: self.prepare_data_fn(data_mode='train'))
    val_spec = tf.estimator.EvalSpec(input_fn=lambda: self.prepare_data_fn(data_mode='val'))
    tf.estimator.train_and_evaluate(model, train_spec, val_spec)

 

點擊以下標題查看更多往期內容:

#投 稿 通 道#

 讓你的論文被更多人看到 

 

如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢? 答案就是:你不認識的人。

總有一些你不認識的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋梁,促使不同背景、不同方向的學者和學術靈感相互碰撞,迸發出更多的可能性。 

PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是最新論文解讀,也可以是學習心得技術乾貨。我們的目的只有一個,讓知識真正流動起來。

來稿標準:

• 稿件確系個人原創作品,來稿需註明作者個人信息(姓名+學校/工作單位+學歷/職位+研究方向) 

• 如果文章並非首發,請在投稿時提醒並附上所有已發佈鏈接 

• PaperWeekly 預設每篇文章都是首發,均會添加“原創”標誌

? 投稿郵箱:

• 投稿郵箱:[email protected] 

• 所有文章配圖,請單獨在附件中發送 

• 請留下即時聯繫方式(微信或手機),以便我們在編輯發佈時和作者溝通

?

現在,在「知乎」也能找到我們了

進入知乎首頁搜索「PaperWeekly」

點擊「關註」訂閱我們的專欄吧

關於PaperWeekly

PaperWeekly 是一個推薦、解讀、討論、報道人工智慧前沿論文成果的學術平臺。如果你研究或從事 AI 領域,歡迎在公眾號後臺點擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。

▽ 點擊 | 閱讀原文 | 加入比賽

    閱讀原文

    赞(0)

    分享創造快樂