From 9923869bad626fa8f5a8e206eedf702087ffdd7f Mon Sep 17 00:00:00 2001 From: Rethakgetse-Manaka Date: Sat, 3 Aug 2024 23:57:22 +0200 Subject: [PATCH 1/3] Able to get containers to communicate with the model. --- attendance_scaler.pkl | Bin 0 -> 719 bytes datasets/output.csv | 1522 +++++++++++++++++ datasets/processor.py | 32 + maestro/LSTM(1).py | 6 +- maestro/test.py | 2 +- models/Docker_Commands | 14 - models/Dockerfile | 17 - models/docker-compose.yml | 19 - python-code/Dockerfile | 23 - .../__pycache__/prediction.cpython-312.pyc | Bin 2525 -> 0 bytes .../__pycache__/scaler.cpython-312.pyc | Bin 643 -> 0 bytes python-code/app.py | 20 +- python-code/docker-compose.yml | 18 + python-code/models.config | 7 - python-code/prediction.py | 2 +- 15 files changed, 1590 insertions(+), 92 deletions(-) create mode 100644 attendance_scaler.pkl create mode 100644 datasets/output.csv create mode 100644 datasets/processor.py delete mode 100644 models/Docker_Commands delete mode 100644 models/Dockerfile delete mode 100644 models/docker-compose.yml delete mode 100644 python-code/Dockerfile delete mode 100644 python-code/__pycache__/prediction.cpython-312.pyc delete mode 100644 python-code/__pycache__/scaler.cpython-312.pyc create mode 100644 python-code/docker-compose.yml delete mode 100644 python-code/models.config diff --git a/attendance_scaler.pkl b/attendance_scaler.pkl new file mode 100644 index 0000000000000000000000000000000000000000..11f20c276777b32d202b3bd9d6397bd77ad1cb9b GIT binary patch literal 719 zcma))O=uHA6vva8*!a=3Qanf?G*ltBvg)DYp|D$X2pEXP6%-VQ+1+Vp+uhk^X18?@ zf*!09#*-5)^dR1ao<$EL9@LAdphXl#^j7g8f|oYVY^)T#_zp8~9y9O%d+*JaeCJ*^ zlNv9xIS)Zfw2-2Z1~y{MB{LduU<3s(nGqxoq>gDr4^eST9K0$niyGgt;6@nu2olle z#q_`;NBVg?2ot%N2$)7NiYa2iB|tO_e1HH3{m_#UhLDW$y(IR-M6&~mG(Ywt7g7on z!M8Ih2bCNzq*vtbL`jHLB?5X;Eu#wh`%0MAWt;lxA#Qu3Y9^MVE7`!JLpEBB~U1pqyFhWLm?z)B*-L~}5< zimFIuwUxUM7hm-m^`!sn_?dl%rvjD3M)~=i^j_-6#M`Nh^-p?dwAX|T&(A{&1TOcc zhbwp(R~0%Q!Ta$6T*ISnJf<}AD*vf>YoCqPl5u|G$K=@knlZBW0DL=V8sBf;Y1sUk z{`%*Km8a`3^v= 1600: + return 7 + elif capacity >= 1400: + return 6 + elif capacity >= 1200: + return 5 + elif capacity >= 1000: + return 4 + elif capacity >= 800: + return 3 + elif capacity >= 600: + return 2 + else: + return 1 + +# Read the CSV data into a DataFrame +file_path = 'datasets/Attendance_data(1).csv' +data = pd.read_csv(file_path) + +df = pd.DataFrame(data) + +# Apply the get_level function to create the Level column +df['Level'] = df['Number_Attended'].apply(get_level) + +# Save the modified DataFrame back to a CSV file +df.to_csv('output.csv', index=False) + +print(df) diff --git a/maestro/LSTM(1).py b/maestro/LSTM(1).py index 1a79dd69..cec6b0b5 100644 --- a/maestro/LSTM(1).py +++ b/maestro/LSTM(1).py @@ -216,5 +216,9 @@ def predict_weekly_attendance(month, start_day): plt.show() # Save the model in the SavedModel format -model.save('attendance_model') +tf.saved_model.save(model, 'attendance_model/1') # model.export('C:/Users/retha/Capstone/occupi/models/attendance_model/1') + +new_model = tf.keras.models.load_model('C:/Users/retha/Capstone/occupi/attendance_model.keras') +new_model.summary() +tf.saved_model.save(new_model, 'serving/') # Save the model in the SavedModel format diff --git a/maestro/test.py b/maestro/test.py index fc15620b..c3991cf8 100644 --- a/maestro/test.py +++ b/maestro/test.py @@ -4,7 +4,7 @@ from sklearn.preprocessing import StandardScaler # Define the URL for the TensorFlow Serving API -url = 'http://localhost:8503/v1/models/attendance_model:predict' +url = 'http://localhost:8501/v1/models/attendance_model:predict' # Define the attendance levels based on the bin ranges attendance_levels = ["0-300", "300-600", "600-900", "900-1200", "1200-1500", "1500-1800", "1800+"] diff --git a/models/Docker_Commands b/models/Docker_Commands deleted file mode 100644 index 51328508..00000000 --- a/models/Docker_Commands +++ /dev/null @@ -1,14 +0,0 @@ -1. docker pull tensorflow/serving - -The following point make sure you're in the directory models -2. docker build -t tensorflow/serving. - -3. docker run -p -d 8501:8501 tensorflow/serving - -4. http://localhost:8501/v1/models/attendance_model - - -the only 3 commands you need are: -1. docker compose -f docker-compose.yml down -2. docker compose -f docker-compose.yml pull -3. docker compose -f docker-compose.yml up -d \ No newline at end of file diff --git a/models/Dockerfile b/models/Dockerfile deleted file mode 100644 index 069e31f3..00000000 --- a/models/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# Use the official TensorFlow Serving image as the base image -FROM tensorflow/serving:latest - -# Set environment variables -ENV MODEL_NAME=attendance_model - -# Create the model directory -RUN mkdir -p /models/${MODEL_NAME} - -# Copy the model from your local directory to the Docker image -COPY attendance_model /models/${MODEL_NAME} - -# Expose the TensorFlow Serving default port -EXPOSE 8501 - -# Set the entrypoint to start TensorFlow Serving with the model -ENTRYPOINT ["sh", "-c", "tensorflow_model_server --port=8501 --model_name=${MODEL_NAME} --model_base_path=/models/${MODEL_NAME}"] diff --git a/models/docker-compose.yml b/models/docker-compose.yml deleted file mode 100644 index 758eb404..00000000 --- a/models/docker-compose.yml +++ /dev/null @@ -1,19 +0,0 @@ -services: - attendance_model: - image: tensorflow/serving:latest - container_name: attendance_model - ports: - - "8501:8501" - environment: - MODEL_NAME: attendance_model - volumes: - - /attendance_model:/models/attendance_model - command: > - sh -c 'tensorflow_model_server --port=8501 --model_name=attendance_model --model_base_path=/models/attendance_model' - networks: - - webnet - restart: on-failure:5 - -networks: - webnet: - external: true \ No newline at end of file diff --git a/python-code/Dockerfile b/python-code/Dockerfile deleted file mode 100644 index 4572a287..00000000 --- a/python-code/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# Use the official Python image from the Docker Hub -FROM python:3.9-slim - -# Set the working directory in the container -WORKDIR /app - -# Copy the requirements file into the container -COPY requirements.txt requirements.txt - -# Install the dependencies -RUN pip install -r requirements.txt - -# Copy the rest of the application code into the container -COPY . . - -# Copy the scaler file into the container -COPY attendance_scaler.pkl attendance_scaler.pkl - -# Expose the port the app runs on -EXPOSE 9000 - -# Define the command to run the application using Gunicorn -CMD ["gunicorn", "app:app", "-b", "0.0.0.0:9000", "-w", "4"] diff --git a/python-code/__pycache__/prediction.cpython-312.pyc b/python-code/__pycache__/prediction.cpython-312.pyc deleted file mode 100644 index 5d39c75803a81e910b8b0b1a2e5dacf7651a7698..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2525 zcmZt|TWlN0agWF2>-e%PiIQbYw3Rq!6orx%OD^r$h!X*=ZMbdRrVgQ+J>0D*(#PXv zZ)sD+u`rB$FkgYcgdi@ev;pG6{UFeO%U)qTSn+BKJdWTW1gM|W({db6LgdpT8 zpg!GSk@AwTV-v^+G%+76BF+ChAs^DD_fbBq1+~EYLO!x8WI~U*<4YNV#V=FE&=jIw zRuvtS#>o{*&0IFCS7E$TwP^0-iJ95#_1SEts$t#ADwJZFV5qp@N^&N_T1lmuU_+Xj zo|~Cz1OZLYa|Y1#4}b{)nw~ulT$tnO*%K}cczX6EuoA~ps?a+vCjt0G_?}(`w1()e zj&i9BWxvPusSObth2g!Py+@k@#VSC3*v_6;xfZEOwwT_|9a$_jEe_?4+7o`niRPwL~yo zQI_6ROp8_xyi`@ynps*hSLsUCm{uX=OZ~-OHCNdX><|->(L!Hgkr+5mz-Ju?bQ66& zJbLHIZ!;fd)-SY$PcC&2%yoxfyZPg91L(+H`)ud%n~s0{OZk9vaNd#U9sm4On1$3J z$35V@8~=YmXx318&kdBltn_Sw+K5Nf7Hxk~Dhj(%586^$+GEyZ?cg4ZV0rJlJqt~+ zgXPe7XYSmtCM=83d4Rh4f4J8ZG((gJ$Axm--L65h?cI1zNd%e7D%C=k{_H=!!1+Oh2L|&vkJzda3-*5Rb(!!uQ;Mw)*$LKeH zZ=bh>J?A>uxAC~|_u$ReB77UoD4p1~k9xW#xZh^18MpmpmLB%>bkgJOm>p=qt$OzK zMNdPIdYq@zga&lCd%cWlCi)h3!reg}yv2DHP9l2DoBaYJ$C^nx<&Dd)cwC=qGR=A; zJL#O#wspd$6A_T%Y=4;)4ZnB4PP!z!rWqXk&r4$myC4rxsuMMGb4nzEG8+0 zD61??iDFpGRZ?L=aJHhDm`OV%K&yJmqRh{C!X&L$F)bD%_`MposKxvyv~ecZh|Xj< z4y{=Qz6ln2N6~B8U7z_Wu2UxIRYlurCQPi948m)di8?k2uSFJKtgG1Mhh{;&S}a2J zn1uNOm}pUw*~er}SuIqT3pX&n#-s|wY=uR8vYk<+WVu>+L|Du+v075}0(4eryaCI7 zgIHi$Q7QP0T1v&#aiL_GHOe9`Dex#0UVCJSZwZdM6IeH#gg>Q(cLNsPaRQSyTxSBd zcr`=seI7`Z+s2=dJ%K_+JUgu_WXesn?aN5XuT!II_1pFJsk^nde*e7llV3WAuR7^M zH}$JlbUT1X#y3+hby6?gjdoKfb|f!srlvZnsk=XIM>l8Ab!N`ppY6;n-ha<|6L#IeXzBqrsSe>;i>k2sSjoPqgP zaBKhA+UvJp|8)P|*FH}@*#AZ=1nWl!H|2?rJh49aFZt-!z(HqXzFps3xX@X+;LKm# zIJZ&%XY+5(jjD6#YImUEL<_K5YHY21ySzT~*`ZGkb%(Rb z{LqOW{W3A`q;pOp=Y(?q*^&pJAfJ@n3MD>_eGqd-X8%0dR{nIfJ>m@K9)wOkj3-*b z|87fQ^2{26z~6c+`_^&v#qsdsr1-_D$;EN;uj3N%8KDSTfbFvxnMnp@`l?$cWE_Nq zw?Q^!UDL5bj91}(G)WbT*MdAHygd`%VMv-Ip3m;9>0b695aCaQn+?xGr{Tw@rsFf@ z6v%k5uz08076n203Jp9$iAPBOH=22b;t==X8^TTTNdOJ0f`j%w2?T|OZwFr%lCH!5 E0mX!BZU6uP diff --git a/python-code/__pycache__/scaler.cpython-312.pyc b/python-code/__pycache__/scaler.cpython-312.pyc deleted file mode 100644 index b9a6e7e713c05b002e0905711de8531fde1583e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 643 zcmZ9IF-sgl6oB8%y0^Q^B~edAf{g_6ib#qOM1l}(#3DqGfE)`l?2hM|z1d}Euh>Sk zOR9iPthEw<-JzY8Z)QC;H^n#e=9~B4%v@Bfqkv;oo$j0wfEyhQhA|l2 z9U=Ze2qB4}NpPkS?O08V00mC=+(E+g+=9?LA;=L!+puEj7`lcY(mBVzdNggUW}TM- z>{TBZFD7n3opmx&AMI)PwN8pxjg*Oy$*>Wyh|9VyDVm<8@fuNvx(}*~-Wbv9%|MyG zy4}-Rr5YbnX17!mL#n51m1=TW*-xsbSEjWF_Ikd?)c?vYY|-r`SwTfoOsO9cXHqOC zk|#0_xKeG=lKN$Z&7@>m;cRWElC?!)?X=UPqRbbZ!5tof`;Wo0|6OsZe96;Y=C86u zrLo|C90c8@?I&5f8;kcr9CE+RTuici_j4x>yAfZJZ?TB}H}wtCw+JCOFmVkZ`Yw!3 z{+#>0@M|Hjz02o6}t_ Mdh>@BIfF$X0QH!Q@Bjb+ diff --git a/python-code/app.py b/python-code/app.py index f8d38acc..28ad08d8 100644 --- a/python-code/app.py +++ b/python-code/app.py @@ -1,23 +1,25 @@ -# app.py from flask import Flask, request, jsonify import logging -from prediction import get_prediction -from scaler import scaler from datetime import datetime, timedelta +from prediction import get_prediction +import joblib # Initialize the Flask application app = Flask(__name__) +# Load the scaler +scaler = joblib.load('attendance_scaler.pkl') + # Function to determine if a given date is a weekend def is_weekend(date): return date.weekday() >= 5 # Function to determine if a given date is a special event (placeholder logic) def is_special_event(date): - special_events_dates = [(7, 4), (12, 25),(4,23),(12,9),(8,5),(3,6),(11,27),(3,10),(7,26)] # Example: 4th of July, Christmas + special_events_dates = [(7, 4), (12, 25), (4, 23), (12, 9), (8, 5), (3, 6), (11, 27), (3, 10), (7, 26)] # Example: 4th of July, Christmas return 1 if (date.month, date.day) in special_events_dates else 0 -@app.route('/predict', methods=['POST']) +@app.route('/predict', methods=['GET']) def predict(): try: # Get current date @@ -29,7 +31,7 @@ def predict(): day_of_month = current_date.day weekend = is_weekend(current_date) special_event = is_special_event(current_date) - # Set factor based on special event + # Set factor based on special event factor = 1.5 if special_event else 1.0 predicted_class, predicted_attendance_level = get_prediction(day_of_week, month, day_of_month, weekend, special_event, scaler, factor) @@ -47,7 +49,7 @@ def predict(): logging.error(f"Error in predict endpoint: {str(e)}") return jsonify({"error": str(e)}), 500 -@app.route('/predict_week', methods=['POST']) +@app.route('/predict_week', methods=['GET']) def predict_week(): try: # Get the current date @@ -68,7 +70,7 @@ def predict_week(): weekend = is_weekend(date) special_event = is_special_event(date) - # Set factor based on special event + # Set factor based on special event factor = 1.5 if special_event else 1.0 # Get prediction @@ -92,4 +94,4 @@ def predict_week(): return jsonify({"error": str(e)}), 500 if __name__ == '__main__': - app.run(debug=True, host='0.0.0.0') + app.run(debug=True, host='0.0.0.0', port=9000) diff --git a/python-code/docker-compose.yml b/python-code/docker-compose.yml new file mode 100644 index 00000000..06d60af6 --- /dev/null +++ b/python-code/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3.8' + +services: + web: + build: . + ports: + - "9000:9000" + depends_on: + - model + + model: + image: tensorflow/serving:latest + environment: + - MODEL_NAME=attendance_model + volumes: + - ../models/attendance_model:/models/attendance_model + ports: + - "8501:8501" diff --git a/python-code/models.config b/python-code/models.config deleted file mode 100644 index a95e1618..00000000 --- a/python-code/models.config +++ /dev/null @@ -1,7 +0,0 @@ -model_config_list: { - config: { - name: 'attendance_model', - base_path: '/models/attendance_model', - model_platform: 'tensorflow' - }, -} \ No newline at end of file diff --git a/python-code/prediction.py b/python-code/prediction.py index faebb626..c054f394 100644 --- a/python-code/prediction.py +++ b/python-code/prediction.py @@ -6,7 +6,7 @@ import logging # Define the URL for the TensorFlow Serving API -url = 'http://localhost:8501/v1/models/attendance_model:predict' +url = 'http://model:8501/v1/models/attendance_model:predict' # Define the attendance levels based on the bin ranges attendance_levels = ["0-300", "300-600", "600-900", "900-1200", "1200-1500", "1500-1800", "1800+"] From b5fa4ab341d9df4589c1c68a640f99d0748be089 Mon Sep 17 00:00:00 2001 From: Rethakgetse-Manaka Date: Sun, 4 Aug 2024 00:02:47 +0200 Subject: [PATCH 2/3] Awaiting improvement from michael --- python-code/Docker_Commands.txt | 29 ----------------------------- python-code/app.py | 4 ++-- 2 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 python-code/Docker_Commands.txt diff --git a/python-code/Docker_Commands.txt b/python-code/Docker_Commands.txt deleted file mode 100644 index b81161b3..00000000 --- a/python-code/Docker_Commands.txt +++ /dev/null @@ -1,29 +0,0 @@ -docker pull tensorflow/serving - -docker run -p 8501:8501 --name tf_serving_attendance \ - --mount type=bind,source=models/attendance_model,target=/models/attendance_model \ - -e MODEL_NAME=attendance_model -t tensorflow/serving - -Docker commands for the flask app - -# Use the official Python image from the Docker Hub -FROM python:3.9-slim - -# Set the working directory in the container -WORKDIR /app - -# Copy the requirements file into the container -COPY requirements.txt requirements.txt - -# Install the dependencies -RUN pip install -r requirements.txt - -# Copy the rest of the application code into the container -COPY . . - -# Expose the port the app runs on -EXPOSE 5000 - -# Define the command to run the application -CMD ["python", "app.py"] - diff --git a/python-code/app.py b/python-code/app.py index 28ad08d8..7b9e24bd 100644 --- a/python-code/app.py +++ b/python-code/app.py @@ -32,7 +32,7 @@ def predict(): weekend = is_weekend(current_date) special_event = is_special_event(current_date) # Set factor based on special event - factor = 1.5 if special_event else 1.0 + # factor = 1.5 if special_event else 1.0 predicted_class, predicted_attendance_level = get_prediction(day_of_week, month, day_of_month, weekend, special_event, scaler, factor) @@ -71,7 +71,7 @@ def predict_week(): special_event = is_special_event(date) # Set factor based on special event - factor = 1.5 if special_event else 1.0 + # factor = 1.5 if special_event else 1.0 # Get prediction predicted_class, predicted_attendance_level = get_prediction(day_of_week, month, day_of_month, weekend, special_event, scaler, factor) From da2656ff7cf9c756109d2fe923b9d871512015ed Mon Sep 17 00:00:00 2001 From: Rethakgetse-Manaka Date: Sun, 4 Aug 2024 00:06:39 +0200 Subject: [PATCH 3/3] Cleaning up folder structure --- attendance_scaler.pkl | Bin 719 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 attendance_scaler.pkl diff --git a/attendance_scaler.pkl b/attendance_scaler.pkl deleted file mode 100644 index 11f20c276777b32d202b3bd9d6397bd77ad1cb9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 719 zcma))O=uHA6vva8*!a=3Qanf?G*ltBvg)DYp|D$X2pEXP6%-VQ+1+Vp+uhk^X18?@ zf*!09#*-5)^dR1ao<$EL9@LAdphXl#^j7g8f|oYVY^)T#_zp8~9y9O%d+*JaeCJ*^ zlNv9xIS)Zfw2-2Z1~y{MB{LduU<3s(nGqxoq>gDr4^eST9K0$niyGgt;6@nu2olle z#q_`;NBVg?2ot%N2$)7NiYa2iB|tO_e1HH3{m_#UhLDW$y(IR-M6&~mG(Ywt7g7on z!M8Ih2bCNzq*vtbL`jHLB?5X;Eu#wh`%0MAWt;lxA#Qu3Y9^MVE7`!JLpEBB~U1pqyFhWLm?z)B*-L~}5< zimFIuwUxUM7hm-m^`!sn_?dl%rvjD3M)~=i^j_-6#M`Nh^-p?dwAX|T&(A{&1TOcc zhbwp(R~0%Q!Ta$6T*ISnJf<}AD*vf>YoCqPl5u|G$K=@knlZBW0DL=V8sBf;Y1sUk z{`%*Km8a`3^v