Skip to content

Commit

Permalink
Couldn't add simple unit test, added ci
Browse files Browse the repository at this point in the history
  • Loading branch information
ma7dev committed Dec 12, 2021
1 parent 6b8ab2a commit eb3f584
Show file tree
Hide file tree
Showing 47 changed files with 921 additions and 657 deletions.
76 changes: 76 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# credits:
# - CI with Jest: https://joelhooks.com/jest-and-github-actions
name: CI
on: pull_request
jobs:
test:
name: Test
# setup global configurations
strategy:
matrix:
node-version: [12.x]
platform: [ubuntu-latest, windows-latest, macos-latest]
# Build OS
runs-on: ${{ matrix.platform }}
# CI
steps:
- uses: actions/checkout@v2
# select nodejs v12
- name: Test using Node.js v${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
# install packages
- name: Install Packages
run: npm i
# create a config file
# - name: Create Config File
# uses: "DamianReeves/write-file-action@v1.0"
# with:
# path: ./config.json
# contents: '{"BITLY_TOKEN": "${{ secrets.BITLY_TOKEN }}","TWITCH_TOKEN": "${{ secrets.TWITCH_TOKEN }}","DISCORD_TOKEN": "${{ secrets.DISCORD_TOKEN }}"}'
# write-mode: overwrite
# # run tests
# - name: Run tests
# run: npm run test:ci
# # conditions with test fails or succeeds
# - name: Tests ✅
# shell: bash
# if: ${{ success() }}
# run: |
# curl \
# -X POST \
# -H 'Accept: application/vnd.github.v3+json' \
# -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
# -d '{
# "context": "tests",
# "state": "success",
# "description": "Tests passed",
# "target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
# }' \
# https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }}
# - name: Tests 🚨
# if: ${{ failure() }}
# shell: bash
# run: |
# curl \
# -X POST \
# -H 'Accept: application/vnd.github.v3+json' \
# -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
# -d '{
# "context": "tests",
# "state": "failure",
# "description": "Tests failed",
# "target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
# }' \
# https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }}
# Code Coverage
# - name: Code Coverage
# uses: codecov/codecov-action@v1
# with:
# token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
# remove the config file
# - name: Remove Config File
# uses: JesseTG/rm@v1.0.2
# with:
# path: "config.json"
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
"test": "tests"
},
"scripts": {
"dev": "prettier --write app/* --tab-width 4 && nodemon app/index",
"dev": "prettier --write src/* --tab-width 4",
"start": "node server",
"dep": "pm2 start app/index",
"dep": "pm2 start src/index",
"test": "jest --watch",
"test:ci": "jest --ci --reporters='default' --reporters='./github-actions-reporter' --coverage && codecov",
"stop": "pm2 stop app/index.js"
"stop": "pm2 stop src/index.js"
},
"repository": {
"type": "git",
Expand Down
38 changes: 19 additions & 19 deletions src/ai/BlendGAN/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@

Y-tech, Kuaishou Technology

### [Project page](https://onion-liu.github.io/BlendGAN) | [Paper](https://arxiv.org/abs/2110.11728)

### [Project page](https://onion-liu.github.io/BlendGAN) | [Paper](https://arxiv.org/abs/2110.11728)

Abstract: *Generative Adversarial Networks (GANs) have made a dramatic leap in high-fidelity image synthesis and stylized face generation. Recently, a layer-swapping mechanism has been developed to improve the stylization performance. However, this method is incapable of fitting arbitrary styles in a single model and requires hundreds of style-consistent training images for each style. To address the above issues, we propose BlendGAN for arbitrary stylized face generation by leveraging a flexible blending strategy and a generic artistic dataset. Specifically, we first train a self-supervised style encoder on the generic artistic dataset to extract the representations of arbitrary styles. In addition, a weighted blending module (WBM) is proposed to blend face and style representations implicitly and control the arbitrary stylization effect. By doing so, BlendGAN can gracefully fit arbitrary styles in a unified model while avoiding case-by-case preparation of style-consistent training images. To this end, we also present a novel large-scale artistic face dataset AAHQ. Extensive experiments demonstrate that BlendGAN outperforms state-of-the-art methods in terms of visual quality and style diversity for both latent-guided and reference-guided stylized face synthesis.*
Abstract: _Generative Adversarial Networks (GANs) have made a dramatic leap in high-fidelity image synthesis and stylized face generation. Recently, a layer-swapping mechanism has been developed to improve the stylization performance. However, this method is incapable of fitting arbitrary styles in a single model and requires hundreds of style-consistent training images for each style. To address the above issues, we propose BlendGAN for arbitrary stylized face generation by leveraging a flexible blending strategy and a generic artistic dataset. Specifically, we first train a self-supervised style encoder on the generic artistic dataset to extract the representations of arbitrary styles. In addition, a weighted blending module (WBM) is proposed to blend face and style representations implicitly and control the arbitrary stylization effect. By doing so, BlendGAN can gracefully fit arbitrary styles in a unified model while avoiding case-by-case preparation of style-consistent training images. To this end, we also present a novel large-scale artistic face dataset AAHQ. Extensive experiments demonstrate that BlendGAN outperforms state-of-the-art methods in terms of visual quality and style diversity for both latent-guided and reference-guided stylized face synthesis._

### Updates

Expand All @@ -19,7 +18,7 @@ Abstract: *Generative Adversarial Networks (GANs) have made a dramatic leap in h

:heavy_check_mark: (2021-11-19) a web demo is integrated to [Huggingface Spaces](https://huggingface.co/spaces) with [Gradio](https://github.com/gradio-app/gradio). See demo: [![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-blue)](https://huggingface.co/spaces/akhaliq/BlendGAN)

:heavy_check_mark: (2021-11-19) Inference code and pretrained models have been released!
:heavy_check_mark: (2021-11-19) Inference code and pretrained models have been released!

![000041](https://user-images.githubusercontent.com/6346064/142623312-3e6f09aa-ce88-465c-b956-a8b4db95b4da.gif)
![000021](https://user-images.githubusercontent.com/6346064/142621044-086cde48-8604-467b-8c43-8768b6670ec2.gif)
Expand All @@ -28,25 +27,25 @@ Abstract: *Generative Adversarial Networks (GANs) have made a dramatic leap in h

You can download the following pretrained models to ./pretrained_models:

| Model | Discription |
| ---- | ---- |
| [blendgan](https://drive.google.com/file/d/1eF04jKMLAb9DvzI72m8Akn5ykWf3EafE/view?usp=sharing) | BlendGAN model (together with style_encoder) |
| [psp_encoder](https://drive.google.com/file/d/14nevG94hNkkwaoK5eJLF1iv78cv5O8fN/view?usp=sharing) | PSP Encoder model |
| [style_encoder](https://drive.google.com/file/d/1EaM0ZYsAMdPkbRz0smLNIlJ1rxVAhbEz/view?usp=sharing) | Individual Style Encoder model (optional) |
| Model | Discription |
| --------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| [blendgan](https://drive.google.com/file/d/1eF04jKMLAb9DvzI72m8Akn5ykWf3EafE/view?usp=sharing) | BlendGAN model (together with style_encoder) |
| [psp_encoder](https://drive.google.com/file/d/14nevG94hNkkwaoK5eJLF1iv78cv5O8fN/view?usp=sharing) | PSP Encoder model |
| [style_encoder](https://drive.google.com/file/d/1EaM0ZYsAMdPkbRz0smLNIlJ1rxVAhbEz/view?usp=sharing) | Individual Style Encoder model (optional) |

## Inference

*Note: If you dislike the deformation in the generated images, `add_weight_index=7` may be a better choice.*
_Note: If you dislike the deformation in the generated images, `add_weight_index=7` may be a better choice._

### 1. Generate image pairs with random face codes

- for latent-guided generation, run:
- for latent-guided generation, run:

```bash
python generate_image_pairs.py --size 1024 --pics N_PICS --ckpt ./pretrained_models/blendgan.pt --outdir results/generated_pairs/latent_guided/
```

- for reference-guided generation, run:
- for reference-guided generation, run:

```bash
python generate_image_pairs.py --size 1024 --pics N_PICS --ckpt ./pretrained_models/blendgan.pt --style_img ./test_imgs/style_imgs/100036.png --outdir results/generated_pairs/reference_guided/
Expand All @@ -73,7 +72,9 @@ jupyter notebook --notebook-dir=./
![demo](./index_files/demo.jpg)

## Bibtex

If you use this code for your research, please cite our paper:

```
@inproceedings{liu2021blendgan,
title = {BlendGAN: Implicitly GAN Blending for Arbitrary Stylized Face Generation},
Expand All @@ -84,30 +85,29 @@ If you use this code for your research, please cite our paper:
```

## Credits

**StyleGAN2 model and implementation:**
https://github.com/rosinality/stylegan2-pytorch
Copyright (c) 2019 Kim Seonghyeon
License (MIT) https://github.com/rosinality/stylegan2-pytorch/blob/master/LICENSE
License (MIT) https://github.com/rosinality/stylegan2-pytorch/blob/master/LICENSE

**IR-SE50 model and implementations:**
https://github.com/TreB1eN/InsightFace_Pytorch
Copyright (c) 2018 TreB1eN
License (MIT) https://github.com/TreB1eN/InsightFace_Pytorch/blob/master/LICENSE

**pSp model and implementation:**
**pSp model and implementation:**
https://github.com/eladrich/pixel2style2pixel
Copyright (c) 2020 Elad Richardson, Yuval Alaluf
License (MIT) https://github.com/eladrich/pixel2style2pixel/blob/master/LICENSE

**Please Note**:

- The CUDA files under the [StyleGAN2 ops directory](./op) are made available under the [Nvidia Source Code License-NC](https://nvlabs.github.io/stylegan2/license.html)
- The face images under the [test_imgs](./test_imgs/face_imgs) directory are selected from the [FFHQ](https://github.com/NVlabs/ffhq-dataset) dataset, which is made available under [Creative Commons BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) license by NVIDIA Corporation.
- The artistic images under the [test_imgs](./test_imgs/style_imgs) directory are collected from [Artstation](https://www.artstation.com), and the copyright remains with the original owners.

- The CUDA files under the [StyleGAN2 ops directory](./op) are made available under the [Nvidia Source Code License-NC](https://nvlabs.github.io/stylegan2/license.html)
- The face images under the [test_imgs](./test_imgs/face_imgs) directory are selected from the [FFHQ](https://github.com/NVlabs/ffhq-dataset) dataset, which is made available under [Creative Commons BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) license by NVIDIA Corporation.
- The artistic images under the [test_imgs](./test_imgs/style_imgs) directory are collected from [Artstation](https://www.artstation.com), and the copyright remains with the original owners.

## Acknowledgements

We sincerely thank all the reviewers for their comments. We also thank Zhenyu Guo for help in preparing the comparison to StarGANv2.
This code borrows heavily from the pytorch re-implementation of StyleGAN2 by [rosinality](https://github.com/rosinality/stylegan2-pytorch).

2 changes: 1 addition & 1 deletion src/ai/BlendGAN/ffhq_dataset/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Download *shape_predictor_68_face_landmarks.dat* here
Download _shape_predictor_68_face_landmarks.dat_ here

```bash
wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
Expand Down
49 changes: 25 additions & 24 deletions src/api/index.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
const express = require('express'),
mongoose = require('mongoose'),
ejs = require('ejs');
const express = require("express"),
mongoose = require("mongoose"),
ejs = require("ejs");

const router = require("./routes/index"),
streamer_router = require("./routes/streamer"),
rank_router = require("./routes/rank"),
validate_router = require("./routes/validate"),
ai_router = require("./routes/ai");

require('dotenv').config({path:'../../.env'});
require("dotenv").config({ path: "../../.env" });

const app = express(),
port = process.env.PORT || 4000;

app.use(express.json())
app.use(express.static(__dirname + '/public')); //Serves resources from public folder
app.set('view engine', 'ejs');
app.use(express.json());
app.use(express.static(__dirname + "/public")); //Serves resources from public folder
app.set("view engine", "ejs");

main().catch(err => console.log(err));
main().catch((err) => console.log(err));

async function main() {
await mongoose.connect(process.env.DATABASE_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
tlsCAFile: "../../ca-certificate.crt"
}).catch(err => {
console.error(err.stack)
process.exit(1)
});
await mongoose
.connect(process.env.DATABASE_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
tlsCAFile: "../../ca-certificate.crt",
})
.catch((err) => {
console.error(err.stack);
process.exit(1);
});
}

app.use('/streamer', streamer_router)
app.use('/rank', rank_router)
app.use('/validate', validate_router)
app.use('/ai', ai_router)
app.use('/', router)

app.use("/streamer", streamer_router);
app.use("/rank", rank_router);
app.use("/validate", validate_router);
app.use("/ai", ai_router);
app.use("/", router);

app.listen(port, () => {
console.log(`localhost:${port}`)
});
console.log(`localhost:${port}`);
});
10 changes: 5 additions & 5 deletions src/api/models/Rank.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const mongoose = require('mongoose');
const mongoose = require("mongoose");

const rankSchema = new mongoose.Schema({
name: { type: String, required: true },
roleId: { type: String, required: true },
channelId: { type: String, required: true },
threshold: { type: Number, required: true }
threshold: { type: Number, required: true },
});

// streamerSchema.methods.stream = function stream() {
Expand All @@ -14,6 +14,6 @@ const rankSchema = new mongoose.Schema({
// console.log(greeting);
// };

module.exports = {
Rank: mongoose.model('Ranks', rankSchema)
}
module.exports = {
Rank: mongoose.model("Ranks", rankSchema),
};
40 changes: 20 additions & 20 deletions src/api/models/Streamer.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
const mongoose = require('mongoose');
const mongoose = require("mongoose");

const twitchInfo = {
twitchName: { type: String, required: true, },
const twitchInfo = {
twitchName: { type: String, required: true },
twitchId: { type: String, required: true },
profileImg: { type: String, default: "" },
}
};

const twitchStats = {
const twitchStats = {
streams: { type: Number, default: 0 },
hosts: { type: Number, default: 0 },
raids: { type: Number, default: 0 },
chats: { type: Number, default: 0 },
views: { type: Number, required: false },
follows: { type: Number, required: false }
}
follows: { type: Number, required: false },
};

const rankInfo = {
const rankInfo = {
rankName: { type: String, default: "" },
points: { type: Number, default: 0 },
activityPoints: { type: Number, default: 0 },
streamsBeforeDemotion: { type: Number, default: 0 }
}
streamsBeforeDemotion: { type: Number, default: 0 },
};

const invitationInfo = {
const invitationInfo = {
invitedUsers: {
type: [Number],
default: []
default: [],
},
invites: {
type: Number,
default: 0
default: 0,
},
eventIds: {
type: [String],
default: []
}
}
default: [],
},
};

const streamerSchema = new mongoose.Schema({
discordId: { type: String, required: true },
...twitchInfo,
...twitchStats,
...rankInfo,
...invitationInfo
...invitationInfo,
});

// streamerSchema.methods.stream = function stream() {
Expand All @@ -52,6 +52,6 @@ const streamerSchema = new mongoose.Schema({
// console.log(greeting);
// };

module.exports = {
Streamer: mongoose.model('Streamers', streamerSchema)
}
module.exports = {
Streamer: mongoose.model("Streamers", streamerSchema),
};
Loading

0 comments on commit eb3f584

Please sign in to comment.