Skip to content

Commit

Permalink
Merge pull request #164 from datalab-mi/enh/new_classification_model
Browse files Browse the repository at this point in the history
New classification model in 12 classes
  • Loading branch information
leihuayi committed Aug 17, 2023
2 parents 3cb7a23 + 6bc40cc commit a052cfe
Show file tree
Hide file tree
Showing 15 changed files with 90 additions and 64 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
SHELL := /bin/bash
DOCKER := $(shell type -p docker)
DC := $(shell type -p docker-compose)
TAG := 3.0
TAG := 3.1
APP_NAME := basegun
REG := ghcr.io
ORG := datalab-mi
Expand Down
17 changes: 9 additions & 8 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,32 @@ RUN apt update && apt install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*

# install python libraries
COPY requirements.txt ./
# install python libraries (except torch)
COPY requirements/ requirements/
ENV PIP_CERT=$CACERT_LOCATION
RUN pip install --upgrade pip \
&& pip --default-timeout=300 install --no-cache-dir -f \
https://download.pytorch.org/whl/cpu/torch_stable.html -r requirements.txt \
RUN pip --default-timeout=300 install --upgrade pip \
&& pip --default-timeout=300 install --no-cache-dir -r requirements/common.txt \
&& rm -r /root/.cache

# launch website
ARG VERSION
ARG MODEL="EffB4_2022-03-02_08"
ARG MODEL="EffB7_2023-03-06_08"
ENV SSL_CERT_FILE=$CACERT_LOCATION
RUN curl -o model.pth https://storage.gra.cloud.ovh.net/v1/AUTH_df731a99a3264215b973b3dee70a57af/basegun-public/models/${MODEL}/${MODEL}.pth
COPY src/ src/
RUN mkdir -p src/weights \
&& mv model.pth src/weights/model.pth \
&& echo '{"app": "'${VERSION}'", "model": "'${MODEL}'"}' > versions.json

# launch website
FROM base as dev
RUN pip --default-timeout=300 install --no-cache-dir -r requirements/dev.txt
CMD ["uvicorn", "src.main:app", "--reload", "--host", "0.0.0.0", "--port", "5000"]

FROM base as test
RUN pip install requests && rm -r /root/.cache
RUN pip install -r requirements/dev.txt && pip install requests && rm -r /root/.cache
COPY tests/ tests/
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "5000"]

FROM base as prod
RUN pip install --no-cache-dir -r requirements/prod.txt
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "5000"]
2 changes: 0 additions & 2 deletions backend/requirements.txt → backend/requirements/common.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
fastapi==0.68.0
uvicorn==0.14.0
torch==1.10.2
torchvision==0.11.3
python-multipart>=0.0.5
gelf-formatter==0.2.1
pyyaml>=5.4.1
Expand Down
3 changes: 3 additions & 0 deletions backend/requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--extra-index-url https://download.pytorch.org/whl/cpu
torch==1.13.0
torchvision==0.14.0
3 changes: 3 additions & 0 deletions backend/requirements/prod.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--extra-index-url https://download.pytorch.org/whl/cpu
torch==1.13.0+cpu
torchvision==0.14.0+cpu
21 changes: 15 additions & 6 deletions backend/src/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@
from torchvision import transforms


CLASSES = ['autre_epaule', 'autre_pistolet', 'epaule_a_levier_sous_garde',
'epaule_a_percussion_silex', 'epaule_a_pompe', 'epaule_a_un_coup', 'epaule_a_verrou',
'pistolet_a_percussion_silex', 'pistolet_semi_auto_moderne', 'revolver']

MODEL_TORCH = Model.efficientnet_b4
INPUT_SIZE = 380
CLASSES = ['autre_pistolet',
'epaule_a_levier_sous_garde',
'epaule_a_pompe',
'epaule_a_un_coup_par_canon',
'epaule_a_verrou',
'epaule_mecanisme_ancien',
'epaule_semi_auto_style_chasse',
'epaule_semi_auto_style_militaire_milieu_20e',
'pistolet_mecanisme_ancien',
'pistolet_semi_auto_moderne',
'revolver',
'semi_auto_style_militaire_autre']

MODEL_TORCH = Model.efficientnet_b7
INPUT_SIZE = 600
device = torch.device('cpu')


Expand Down
4 changes: 2 additions & 2 deletions backend/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def test_upload_and_logs(self):

# checks that the json result is as expected
self.assertEqual(res["label"], "revolver")
self.assertAlmostEqual(res["confidence"], 99.53, places=1)
self.assertAlmostEqual(res["confidence"], 98.43, places=1)
self.assertTrue(res["confidence_level"], "high")
self.assertTrue("ovh" in res["path"])
# checks that written file is exactly the same as input file
Expand All @@ -72,7 +72,7 @@ def test_upload_and_logs(self):
self.assertTrue("-" in log["_bg_user_id"])
self.assertEqual(log["_bg_geolocation"], geoloc)
self.assertEqual(log["_bg_label"], "revolver")
self.assertAlmostEqual(log["_bg_confidence"], 99.53, places=1)
self.assertAlmostEqual(log["_bg_confidence"], 98.43, places=1)
self.assertTrue(log["_bg_upload_time"]>=0)

def test_feedback_and_logs(self):
Expand Down
2 changes: 1 addition & 1 deletion backend/tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ def test_predict_image(self):
with open(path, 'rb') as f:
res = predict_image(self.model, f.read())
self.assertEqual(res[0], "revolver")
self.assertAlmostEqual(res[1], 99.53, places=1)
self.assertAlmostEqual(res[1], 98.43, places=1)
4 changes: 2 additions & 2 deletions frontend/cypress/e2e/get-basegun-result.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ describe('Get Basegun result', () => {
cy.visit('/instructions')
cy.getByDataTestid('select-file').as('fileInput')
cy.intercept('POST','/api/upload').as('upload')
cy.get('@fileInput').selectFile('./cypress/images/autre-pistolet.jpg', { force: true })
cy.get('@fileInput').selectFile('./cypress/images/pistolet-ancien-a-percussion-monocoup.jpg', { force: true })
cy.wait('@upload').then(({ response }) => {
expect(response.statusCode).to.eq(200)
})
cy.url().should('contain','/resultat')
cy.getByDataTestid('legal-category').contains('Catégorie A, B ou D')
cy.getByDataTestid('legal-category').contains('D')
cy.getByDataTestid('dummy-button')
.should('be.disabled')
.contains('Pas de guide de vérification')
Expand Down
Binary file modified frontend/cypress/images/autre-pistolet.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "basegun",
"version": "3.0.0",
"version": "3.1.0",
"private": true,
"scripts": {
"preview": "vite preview",
Expand Down
90 changes: 51 additions & 39 deletions frontend/src/utils/firearms-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,67 +26,79 @@ import autreEpauleCartridges from '@/assets/guide-factice/images/autre_epaule/au
import autreEpauleBalls from '@/assets/guide-factice/images/autre_epaule/autre-epaule-balls.jpg'

export const results = {
revolver: {
displayLabel: 'revolver',
category: 'B ou D',
mention: "B - Soumise à autorisation<br>D - Libre d'acquisition et de détention",
isDummyTypology: true,
stepsNumber: 4,
},
pistolet_semi_auto_moderne: {
displayLabel: 'pistolet semi-automatique moderne',
category: 'B',
mention: 'Soumise à autorisation',
isDummyTypology: true,
stepsNumber: 4,
},
pistolet_a_percussion_silex: {
displayLabel: 'pistolet à mécanisme ancien',
category: 'D',
mention: "Libre d'acquisition et de détention",
isDummyTypology: false,
},
autre_pistolet: {
displayLabel: 'pistolet divers',
category: 'A, B ou D',
mention: "A - Interdite<br>B - Soumise à autorisation<br>D - Libre d'acquisition et de détention",
isDummyTypology: false,
},
epaule_a_percussion_silex: {
displayLabel: "arme d'épaule à mécanisme ancien",
category: 'D',
mention: "Libre d'acquisition et de détention",
isDummyTypology: false,
},
epaule_a_un_coup: {
displayLabel: "arme d'épaule à un coup par canon",
category: 'C',
mention: 'Soumise à déclaration',
isDummyTypology: false,
},
epaule_a_levier_sous_garde: {
displayLabel: "arme d'épaule à levier de sous-garde",
category: 'B ou C',
mention: 'B - Soumise à autorisation<br>C - Soumise à déclaration',
isDummyTypology: false,
},
epaule_a_pompe: {
displayLabel: "arme d'épaule à pompe",
category: 'B ou C',
mention: 'B - Soumise à autorisation<br>C - Soumise à déclaration',
isDummyTypology: false,
},
epaule_a_un_coup_par_canon: {
displayLabel: "arme d'épaule à un coup ou un coup par canon",
category: 'C',
mention: 'Soumise à déclaration',
isDummyTypology: false,
},
epaule_a_verrou: {
displayLabel: "arme d'épaule à verrou",
category: 'B ou C',
mention: 'B - Soumise à autorisation<br>C - Soumise à déclaration',
isDummyTypology: false,
stepsNumber: 4,
},
epaule_a_pompe: {
displayLabel: "arme d'épaule à pompe",
epaule_mecanisme_ancien: {
displayLabel: "arme d'épaule à mécanisme ancien",
category: 'D',
mention: "Libre d'acquisition et de détention",
isDummyTypology: false,
},
epaule_semi_auto_style_chasse: {
displayLabel: "arme d'épaule semi-automatique",
category: 'B ou C',
mention: 'B - Soumise à autorisation<br>C - Soumise à déclaration',
isDummyTypology: false,
},
autre_epaule: {
displayLabel: "arme d'épaule non manuelle",
epaule_semi_auto_style_militaire_milieu_20e: {
displayLabel: "arme d'épaule semi-automatique ou automatique",
category: 'A, B ou C',
mention: 'A - Interdite<br>B - Soumise à autorisation<br>C - Soumise à déclaration',
isDummyTypology: false,
},
pistolet_semi_auto_moderne: {
displayLabel: 'pistolet semi-automatique',
category: 'B',
mention: 'Soumise à autorisation',
isDummyTypology: true,
stepsNumber: 4,
},
pistolet_mecanisme_ancien: {
displayLabel: 'pistolet à mécanisme ancien',
category: 'D',
mention: "Libre d'acquisition et de détention",
isDummyTypology: false,
},
revolver: {
displayLabel: 'revolver',
category: 'B ou D',
mention: "B - Soumise à autorisation<br>D - Libre d'acquisition et de détention",
isDummyTypology: true,
stepsNumber: 4,
},
semi_auto_style_militaire_autre: {
displayLabel: "arme semi-automatique ou automatique",
category: 'A, B ou C',
mention: 'A - Interdite<br>B - Soumise à autoriszation<br>C - Soumise à déclaration',
isDummyTypology: true,
stepsNumber: 4,
},
Expand All @@ -110,8 +122,8 @@ export const guideFacticeSelectOption = {
video: pistoletSemiAutoModerne2Video,
},
},
autre_epaule_text_option: 'Sélectionner ce que vous voyez sur l’arme',
autre_epaule: {
semi_auto_style_militaire_autre_text_option: 'Sélectionner ce que vous voyez sur l’arme',
semi_auto_style_militaire_autre: {
bouton_dessus: {
label: 'bouton au-dessus chargeur',
value: 'bouton_dessus',
Expand Down Expand Up @@ -186,7 +198,7 @@ export const guideFacticeSelectAmmo = {
img_ammo: pistoletSemiAutoModerneBalls,
},
},
autre_epaule: {
semi_auto_style_militaire_autre: {
cartouches: {
label: 'cartouches',
value: 'cartouches',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/About.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const imgs = ref([
<div />
<p>
A ce jour, Basegun permet de prendre en photo une arme à feu et d'obtenir un
résultat parmi 10 typologies possibles. Ce résultat donne une indication sur la ou les catégories légales
résultat parmi 12 typologies possibles. Ce résultat donne une indication sur la ou les catégories légales
à laquelle l'arme appartient.
</p>
<p class="fr-callout">
Expand Down

0 comments on commit a052cfe

Please sign in to comment.