Code Monkey home page Code Monkey logo

reclearn's Introduction

Hello World👋

我是潜心,一位喜欢钻研推荐算法的初学者。

  • ⚒️ Python/Tensorflow
  • 📦 Recommender System with TF2.0
  • ✏️ 公众号:潜心学习的潜心
  • 🏫 硕士在读
  • 🏢 美团推荐算法实习生

reclearn's People

Contributors

ziyaogeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reclearn's Issues

FM模型实现细节请教

你好,请问下FM模型51行
inputs = inputs + tf.convert_to_tensor(self.index_mapping)
为什么要给inputs加上 index_mapping 呢?index_mapping的作用是什么?
辛苦解答

SASRec error——problem solved

I tried to run SASRec project, but there was something wrong. But i don't know how to solve this problem yet. Probobaly because of the version of tensorflow. Can not use tf2.3. Tf2.0 works well.

3837/3837 [==============================] - ETA: 0s - loss: 0.5068Traceback (most recent call last):
File "train.py", line 62, in
batch_size=batch_size,
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py", line 108, in _method_wrapper
return method(self, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py", line 1133, in fit
return_dict=True)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py", line 108, in _method_wrapper
return method(self, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py", line 1379, in evaluate
tmp_logs = test_function(iterator)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/def_function.py", line 780, in call
result = self._call(*args, **kwds)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/def_function.py", line 823, in _call
self._initialize(args, kwds, add_initializers_to=initializers)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/def_function.py", line 697, in _initialize
*args, **kwds))
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/function.py", line 2855, in _get_concrete_function_internal_garbage_collected
graph_function, _, _ = self._maybe_define_function(args, kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/function.py", line 3213, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/function.py", line 3075, in _create_graph_function
capture_by_value=self._capture_by_value),
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/func_graph.py", line 986, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/def_function.py", line 600, in wrapped_fn
return weak_wrapped_fn().wrapped(*args, **kwds)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/func_graph.py", line 973, in wrapper
raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1224 test_function  *
    return step_function(self, iterator)
/content/drive/My Drive/Recommender-System-with-TF2.0-master/SASRec/model.py:63 call  *
    dense_inputs, sparse_inputs, seq_inputs, item_inputs = inputs

ValueError: not enough values to unpack (expected 4, got 2)

NFM模型实现是不是少了pooling层

def call(self, inputs):
# Inputs layer
sparse_inputs = inputs
# Embedding layer
sparse_embed = [self.embed_layers['embed_{}'.format(i)](sparse_inputs[:, i])
for i in range(sparse_inputs.shape[1])]
sparse_embed = tf.transpose(tf.convert_to_tensor(sparse_embed), [1, 0, 2]) # (None, filed_num, embed_dim)
# Bi-Interaction Layer
sparse_embed = 0.5 * (tf.pow(tf.reduce_sum(sparse_embed, axis=1), 2) -
tf.reduce_sum(tf.pow(sparse_embed, 2), axis=1)) # (None, embed_dim)
# Concat
# 这里是不是和原论文有出入,少了pooling层
#x = tf.concat([dense_inputs, sparse_embed], axis=-1)
# BatchNormalization
x = sparse_embed
x = self.bn(x, training=self.bn_use)
# Hidden Layers
x = self.dnn_network(x)
outputs = tf.nn.sigmoid(self.dense(x))
return outputs

SASRec训练出错

没改动代码,训练完一个epoch就报错啊
ValueError: in user code:

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1224 test_function  *
    return step_function(self, iterator)
/content/dataset/SASRec/model.py:63 call  *
    dense_inputs, sparse_inputs, seq_inputs, item_inputs = inputs

ValueError: not enough values to unpack (expected 4, got 2)

MF/model.py的第102,103行,参数报错

self.mf_layer = MF_layer(num_users, num_items, latent_dim, implicit, 
                                        use_bias,user_reg, item_reg, user_bias_reg, item_bias_reg)

这句出错:提示要求4-9个参数,当前传入了10个

我把这里的implicit删掉了就能运行了,不知道对不对,求大神解答!

SASRec 模型中正负样本划分问题

作者您好:
在SASRec模型的数据处理文件util.py中,有

implicit dataset

data_df.loc[data_df.label < 2, 'label'] = 0
data_df.loc[data_df.label >= 2, 'label'] = 1
可以理解为将评分小于2的视为负样本,但是在之后构造训练集和测试集的时候,这个负样本并没有考虑到,还是以用户交互过的物品作为正样本,未交互过的视为负样本。因此这儿根据评分划分正负样本没有意义吧?
不知道我的理解对不对?

SASRec 模型疑問,Key masking 以及 Query masking

作者您好,我在閱讀您的代碼時,有一個地方怎麼想都想不通,想請教您的意見

程式碼如下,當 x 通過權重 wk 和 wk 之後會得到 key 和 query,接下來就會通過下面兩個 masking,我很好奇為何這邊要針對 key 和 query 做 masking。

# Key Masking
    key_masks = tf.sign(tf.abs(tf.reduce_sum(k, axis=-1)))  # (None, seq_len)
    key_masks = tf.tile(tf.expand_dims(key_masks, 1), [1, q.shape[1], 1])  # (None, seq_len, seq_len)

    paddings = tf.ones_like(scaled_att_logits) * (-2 ** 32 + 1)
    outputs = tf.where(tf.equal(key_masks, 0), paddings, scaled_att_logits)  # (None, seq_len, seq_len)

# Query Masking
    query_masks = tf.sign(tf.abs(tf.reduce_sum(q, axis=-1)))  # (None, seq_len)
    query_masks = tf.tile(tf.expand_dims(query_masks, -1), [1, 1, q.shape[1]])  # (None, seq_len, seq_len)
    outputs *= query_masks

依照第一行 tf.sign(tf.abs(tf.reduce_sum(k, axis=-1))) 的作用是將 key embedding 中的最後一個維度進行總和、絕對值以及 tf.sign,返回的值為 0 和 1,通常將 embedding 加總後不太可能剛好是 0 ,一定是正負數,通過 tf.abs 後只剩下正數,然後通過 tf.sign 就會形成全部都是 1 的矩陣,也就是上面的 key_masks,請問為何這裏要進行加總判斷的動作 ?

关于wide&deep输入疑问

def call(self, inputs, **kwargs):
    sparse_embed = tf.concat([self.embed_layers['embed_{}'.format(i)](inputs[:, i])
                              for i in range(inputs.shape[1])], axis=-1)
    x = sparse_embed  # (batch_size, field * embed_dim)
    # Wide
    wide_inputs = inputs + tf.convert_to_tensor(self.index_mapping)
    # wide_inputs = inputs
    wide_out = self.linear(wide_inputs)
    # Deep
    deep_out = self.dnn_network(x)
    deep_out = self.final_dense(deep_out)
    # out
    outputs = tf.nn.sigmoid(0.5 * wide_out + 0.5 * deep_out)
    return outputs

您好,关于wide中的inputs有一个疑问:为什么要加上self.index_mapping?

Caser训练过程的疑问

您好,我想请问一下为什么我在跑Caser模型的时候,得到的HR和NDCG结果是越来越差,loss越来越高呀?

關於 DIN 的 Attention weight 的疑問

作者您好,我在比較論文與程式碼的 attention unit 區塊,關於 Out Product 這塊不是很瞭解,程式碼以及截圖如下:

# q, k, out product should concat
info = tf.concat([q, k, q - k, q * k], axis=-1)

截圖 2020-12-16 下午4 45 57

比較完程式碼之後,我才知道 Out Product 指的是把 q (advertising embedding) 和 k (behaviors embeddings) 做相乘和相減 (原本我以為數學上的 Outer product XD),在論文中對這個操作只有提到一句話:

a(·) adds the out product of them to feed into the subsequent network, which is an explicit knowledge to help relevance modeling.

我猜測這樣做的目的是因為神經網路只具有非線性組合的能力,像相減相乘是比較難學的,不曉得作者您的想法是如何,還是有其他的 insight 可以讓我知道的。

关于DeepFM的二阶特征实现

	def call(self, inputs, **kwargs):
		sparse_inputs = inputs
		# embedding
		sparse_embed = tf.concat([self.embed_layers['embed_{}'.format(i)](sparse_inputs[:, i])
                                  for i in range(sparse_inputs.shape[1])], axis=-1)  # (batch_size, embed_dim * fields)
		# wide
		sparse_inputs = sparse_inputs + tf.convert_to_tensor(self.index_mapping)
		wide_inputs = {'sparse_inputs': sparse_inputs,
					   'embed_inputs': tf.reshape(sparse_embed, shape=(-1, sparse_inputs.shape[1], self.embed_dim))}
		wide_outputs = self.fm(wide_inputs)  # (batch_size, 1)
		# deep
		deep_outputs = self.dnn(sparse_embed)
		deep_outputs = self.dense(deep_outputs)  # (batch_size, 1)
		# outputs
		outputs = tf.nn.sigmoid(tf.add(wide_outputs, deep_outputs))
		return outputs

您好关于deepfm部分,有没有实现二阶特征,就是这个链接的中提到的:https://github.com/zxxwin/tf2_deepfm

AFM模型的复现问题

试了AFM原论文提供的代码,发现AFM的结果相对FM基本没有提升(复现环节出现问题),请问你们提供的代码对AFM相比FM的有效性进行测试了吗?AFM相比FM能否获得性能的提升?

AttRec 資料集中正負樣本劃分的問題

作者您好,AttRec 的資料處理程式碼中,依照您 README.md 的敘述,大於等於 trans_score 作為正樣本,小於 trans_score 作為負樣本,用戶沒看過的電影也會被當成負樣本

    # implicit dataset
    data_df.loc[data_df.label < trans_score, 'label'] = 0
    data_df.loc[data_df.label >= trans_score, 'label'] = 1

但是我在看程式碼時,發現用戶評分小於 trans_score 的電影卻會被分為正樣本。我發現問題在以下程式碼:

        pos_list = df['item_id'].tolist()
        def gen_neg():
            neg = pos_list[0]
            while neg in pos_list:
                neg = random.randint(1, item_id_max)
                return neg

使用 gen_neg 生成負樣本時,只有檢查 neg 是否在 pos_list 裡,但是 pos_list 卻是包含所有的 item_id,沒有是否為正負樣本的判斷,這樣會導致把評分小於 trans_score 的資料被分為正樣本,想請問作者這邊的問題。

ml数据集提取label的问题

在致谢中有一段
**”
在使用movielens的utils.py文件中,trans_score并不能指定正负样本,应将

data_df.loc[data_df.label < trans_score, 'label'] = 0
data_df.loc[data_df.label >= trans_score, 'label'] = 1
更改为:

data_df = data_df[data_df.label >= trans_score]
“**

因为我也是用这个方法处理ml数据集的,不明白为什么最初的方法不可以,我测试了下是没有问题的

fix SASRec模型的mask维度问题

    def call(self, q, k, v, mask):
        q = self.wq(q)  # (None, seq_len, d_model)
        k = self.wk(k)  # (None, seq_len, d_model)
        v = self.wv(v)  # (None, seq_len, d_model)

        # split d_model into num_heads * depth, and concatenate
        q = tf.reshape(tf.concat([tf.split(q, self.num_heads, axis=2)], axis=0),
                       (-1, q.shape[1], q.shape[2] // self.num_heads))  # (None * num_heads, seq_len, d_model // num_heads)
        k = tf.reshape(tf.concat([tf.split(k, self.num_heads, axis=2)], axis=0),
                       (-1, k.shape[1], k.shape[2] // self.num_heads))  # (None * num_heads, seq_len, d_model // num_heads)
        v = tf.reshape(tf.concat([tf.split(v, self.num_heads, axis=2)], axis=0),
                       (-1, v.shape[1], v.shape[2] // self.num_heads))  # (None * num_heads, seq_len, d_model // num_heads)

        # 改动在这儿 >>process mask for multi_head
        mask_ = tf.tile(mask, multiples=[1, 1, self.num_heads])
        mask = tf.reshape(tf.concat([tf.split(mask_, self.num_heads, axis=2)], axis=0),
                       (-1, q.shape[1], q.shape[2] // self.num_heads))  # (None * num_heads, seq_len, d_model // num_heads)
        # 改动结束
        # attention
        scaled_attention = scaled_dot_product_attention(q, k, v, mask, self.causality)  # (None * num_heads, seq_len, d_model // num_heads)

        # Reshape
        outputs = tf.concat(tf.split(scaled_attention, self.num_heads, axis=0), axis=2)  # (N, seq_len, d_model)

        return outputs

FFM代码问题请教

在求教二阶交叉信息的时候,embedding_lookup之后应该是一个batch,filed_num,field_num,k的矩阵,
后面做交叉之前为什么要做这一步的reduce_sum
latent_vector = tf.reduce_sum(tf.nn.embedding_lookup(self.v, inputs), axis=1)

我理解的代码应该是这样的:

latent_vector = tf.nn.embedding_lookup(self.v, inputs) # (batch_size, field_num, field_num, k)
for i in range(self.field_num):
    for j in range(i+1, self.field_num):
        second_order += tf.reduce_sum(latent_vector[:, i, j] * latent_vector[:, j, i], axis=1, keepdims=True)

关于wide&deep中的wide输入疑问

def call(self, inputs, **kwargs):
    sparse_embed = tf.concat([self.embed_layers['embed_{}'.format(i)](inputs[:, i])
                              for i in range(inputs.shape[1])], axis=-1)
    x = sparse_embed  # (batch_size, field * embed_dim)
    # Wide
    wide_inputs = inputs + tf.convert_to_tensor(self.index_mapping)
    wide_out = self.linear(wide_inputs)
    # Deep
    deep_out = self.dnn_network(x)
    deep_out = self.final_dense(deep_out)
    # out
    outputs = tf.nn.sigmoid(0.5 * wide_out + 0.5 * deep_out)
    return outputs

SASRec中的数据处理问题

你这样写的话,数据集里面就会出现label全是0的情况。

data_df.loc[data_df.label >= 2, 'label'] = 1
data_df.loc[data_df.label < 2, 'label'] = 0

应该将这两行数据顺序颠倒一下才对吧。

data_df.loc[data_df.label < 2, 'label'] = 0
data_df.loc[data_df.label >= 2, 'label'] = 1

din中seq_inputs的形状问题?

dense_inputs, sparse_inputs, seq_inputs, item_inputs = inputs这一步,seq_inputs的shape是不是[batch_size, seq_length, field_num]格式的?我用数据测试了一下,
生成的形状好像是[batch_size, 40, 2]

tf版本

tensorflow2.3运行,SASRec
This message will be only logged once.
952/952 [==============================] - ETA: 0s - loss: 0.4448Traceback (most recent call last):
File "train_ifeng.py", line 59, in
batch_size=batch_size,
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 108, in _method_wrapper
return method(self, *args, **kwargs)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 1133, in fit
return_dict=True)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 108, in _method_wrapper
return method(self, *args, **kwargs)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 1379, in evaluate
tmp_logs = test_function(iterator)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 780, in call
result = self._call(*args, **kwds)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 823, in _call
self._initialize(args, kwds, add_initializers_to=initializers)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 697, in _initialize
*args, **kwds))
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 2855, in _get_concrete_function_internal_garbage_collected
graph_function, _, _ = self._maybe_define_function(args, kwargs)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 3213, in _maybe_define_function
graph_function = self._create_graph_function(args, kwargs)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 3075, in _create_graph_function
capture_by_value=self._capture_by_value),
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/func_graph.py", line 986, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 600, in wrapped_fn
return weak_wrapped_fn().wrapped(*args, **kwds)
File "/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/func_graph.py", line 973, in wrapper
raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:

/data/chengt1/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:1224 test_function  *
    return step_function(self, iterator)
/data/chengt1/SASRec_Recall/model.py:55 call  *
    dense_inputs, sparse_inputs, seq_inputs, item_inputs = inputs

ValueError: not enough values to unpack (expected 4, got 2)

是不认可,def summary(self)这种输入写法吗?

din模型训练有问题

你好,din模型和你csdn上写的不一样,csdn上输入有用户id,github上没有了,为啥?而且github上的运行会报错

DIEN

您好,后面会出DIEN的tf2.x的代码复现吗

GPU机器上运行报错问题

你好,我在笔记本上运行WDL代码,完全没有问题,但是把代码迁移到服务器上后,报错:ValueError: as_list() is not defined on an unknown TensorShape. 请问下有谁遇到过这个问题吗?怎么解决呢

SASRec error

你好,model.py中
/data/chengt1/SASRec_Recall/model.py:55 call *
dense_inputs, sparse_inputs, seq_inputs, item_inputs = inputs

ValueError: not enough values to unpack (expected 4, got 2)

报错,请帮忙指点下,谢谢。

建议数据输入方式使用tfrecords

发现代码中都是使用csv、txt、pkl等方式给模型喂数据,虽然学习起来简单,但是却没办法在工业直接复用,工业数据基本都是通过tfrecords方式进行训练。只有经得起大数据量工业验证的代码,才是真正的好代码。

deepfm模型的fm实现和FM模型不一样

两部分的FM输入不一样:
FM模型的实现以连续特征+离散one-hot特征作为输入,再映射隐向量,计算一阶二阶,符合论文;
deepFM模型的FM实现以连续特征+离散embedding特征作为输入,再次映射隐向量计算。(并且没有和deep部分共享隐向量)
此处是否有误?

關於 AttRec 在 predict 時的操作

作者您好,關於 AttRec 這份模型我有些疑問,就是在預測時會使用到 Next positive item 的 embedding,照理來說預測時是不能夠把真正的 Next positive item 輸入給模型,這樣等於是把正確答案丟給模型,請問真正在預測時,要如何得到 pos_scoresneg_scores 呢 ?

以下是程式碼中使用到 pos_embed 時,會讓我產生的疑問:

 # combine
 pos_scores = self.w * tf.reduce_sum(tf.multiply(short_interest, pos_embed), axis=-1, keepdims=True) \+ 
                        (1 - self.w) * tf.reduce_sum(pos_long_interest, axis=-1, keepdims=True)  # (None, 1)
 neg_scores = self.w * tf.reduce_sum(tf.multiply(short_interest, neg_embed), axis=-1, keepdims=True) \+
                       (1 - self.w) * tf.reduce_sum(neg_long_interest, axis=-1, keepdims=True)  # (None, 1)
self.add_loss(tf.reduce_mean(-tf.math.log(tf.nn.sigmoid(pos_scores - neg_scores))))

AFM

afm代码里好像没有看到一次项w0+wx

NFM/model/call中有一个未定义的变量

作者您好: NFM/model/call 54行左右Concat里:x = tf.concat([dense_inputs, sparse_embed], axis=-1) 这里sparse_embed前面并没有定义啊,函数参数列表也没有,是怎么跑通的?

SASRec模型多头注意力问题

代码参数中num_heads参数为1,当我调整为2时间,就会报错:
InvalidArgumentError: 2 root error(s) found.
(0) Invalid argument: condition [512,200,1], then [1024,200,200], and else [1024,200,200] must be broadcastable
[[node sas_rec_4/encoder_layer_8/multi_head_attention_8/SelectV2 (defined at :38) ]]
[[div_no_nan/ReadVariableOp_1/_92]]
(1) Invalid argument: condition [512,200,1], then [1024,200,200], and else [1024,200,200] must be broadcastable
[[node sas_rec_4/encoder_layer_8/multi_head_attention_8/SelectV2 (defined at :38) ]]
0 successful operations.
0 derived errors ignored. [Op:__inference_train_function_21054]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.