In this post, I demonstrate a Streamlit app that I have created that can be used to classify microstructures of different types.
I trained a neural network using CrysX-NN library, on synthetic microstructures of 4 types as shown in this notebook.
Check out the Streamlit App below (Source code is provided below the app)
Source Code:
import streamlit as st import matplotlib.pyplot as plt import numpy as np rng = np.random.default_rng() from pymks import ( generate_multiphase, ) from crysx_nn import network import session_state from streamlit.script_runner import RerunException from streamlit.script_request_queue import RerunData state = session_state.get(rndm_indx=5) @st.cache def create_and_load_model(): nInputs = 100*100 # No. of nodes in the input layer neurons_per_layer = [500, 4] # Neurons per layer (excluding the input layer) activation_func_names = ['ReLU', 'Softmax'] nLayers = len(neurons_per_layer) nEpochs = 4 batchSize = 32 # No. of input samples to process at a time for optimization # Create the crysx_nn neural network model model = network.nn_model(nInputs=nInputs, neurons_per_layer=neurons_per_layer, activation_func_names=activation_func_names, batch_size=batchSize, device='CPU', init_method='Xavier') # Load the preoptimized weights and biases model.load_model_weights('NN_crysx_microstructure_96_weights_streamlit') model.load_model_biases('NN_crysx_microstructure_96_biases_streamlit') return model @st.cache def generate_microstructures(nSamples_per_type, width, height): grain_sizes = [(30, 5), (10, 40), (15, 15), (5, 30)] seeds = [10, 99, 4, 36] data_synth = np.concatenate([ generate_multiphase(shape=(nSamples_per_type, width, height), grain_size=grain_size, volume_fraction=(0.5, 0.5), percent_variance=0.2, # seed=seed ) for grain_size, seed in zip(grain_sizes, seeds) ]) return data_synth microstructure_data = generate_microstructures(20,100,100) microstructures_labels = np.concatenate([np.ones(20)*0,np.ones(20)*1,np.ones(20)*2,np.ones(20)*3]) model = create_and_load_model() # @st.cache def make_sidebar(): # st.sidebar.markdown("## [CrysX-NN](https://github.com/manassharma07/crysx_nn)") st.sidebar.write('\n\n ## Neural Network Library Used') st.sidebar.image('logo_crysx_nn-min.png') st.sidebar.caption('https://github.com/manassharma07/crysx_nn') st.sidebar.write('## Neural Network Architecture Used') st.sidebar.write('1. **Inputs**: Flattened 100x100=10,000') st.sidebar.write('2. **Hidden layer** of size **500** with **ReLU** activation Function') st.sidebar.write('3. **Output layer** of size **4** with **Softmax** activation Function') st.sidebar.write('Training was done for 4 epochs with Categorical Cross Entropy Loss function using [Stochastic Gradient Descent; learning rate=0.02; batch size of 32].') st.sidebar.image('neural_network_visualization_25.png') st.sidebar.caption('Nerual Network Schematic') make_sidebar() st.write('# Microstructure Classification') st.write('## using a `CrysX-NN` neural network model') st.write('### We have microstructures of 4 types:') col1, col2, col3, col4 = st.columns(4) col1.header('Type 1') col1.write('This has 6 times more grain boundaries along the x-axis than the y-axis.') col2.header('Type 2') col2.write('This has 4 times more grain boundaries along the y-axis than the x-axis.') col3.header('Type 3') col3.write('This has the same number of grain boundaries along the x-axis as well as the y-axis.') col4.header('Type 4') col4.write('This has 6 times more grain boundaries along the y-axis than the x-axis.') st.image('microstructures_4_types-min.png') st.write('### The following is a random `100x100` pixel picture of a microstructure of one of these 4 types.') ## The pyplot takes up a lot of screen # fig, ax = plt.subplots() # ax.imshow(microstructure_data[state.rndm_indx,:,:]) # ax.set_axis_off() # st.pyplot(fig) # So we use matplotlib to save an image instead plt.imsave('processed_tensor.png',microstructure_data[state.rndm_indx,:,:], cmap='viridis') st.image('processed_tensor.png', width=200) st.write('### Can you guess which type is it?') option = st.selectbox('Your Answer', ('Choose an option', 'Type 1', 'Type 2', 'Type 3', 'Type 4'), key=state.rndm_indx) if option != 'Choose an option': st.write('You selected:', option) st.write('### True Type: '+str(int(microstructures_labels[state.rndm_indx])+1)) input = (microstructure_data[state.rndm_indx,:,:] - 0.5) / 0.5 input = input.reshape(1, 10000) predictions = model.predict(input.astype(np.float32), loss_func_name='BCE') # Get the maximum probability certainty = np.max(predictions) # Get the index of the maximum probability output = np.argmax(predictions) # st.write(predictions) st.write('### Neural Network Prediction : '+str(int(output+1))) st.write('### Certainty: '+ str(certainty*100)+' %') if st.button('Next sample'): state.rndm_indx = rng.integers(0, microstructure_data.shape[0]) # option = st.selectbox('Your Answer', # ('Choose an option', 'Type 1', 'Type 2', 'Type 3', 'Type 4')) option = None raise RerunException(RerunData()) st.write('### Code used for training the neural network: [Jupyter Notebook](https://github.com/manassharma07/crysx_nn/blob/main/examples/Microstructures_Classification_CPU.ipynb)')
I’m a physicist specializing in computational material science with a PhD in Physics from Friedrich-Schiller University Jena, Germany. I write efficient codes for simulating light-matter interactions at atomic scales. I like to develop Physics, DFT, and Machine Learning related apps and software from time to time. Can code in most of the popular languages. I like to share my knowledge in Physics and applications using this Blog and a YouTube channel.